質問

保護された修飾子を含む奇妙なエラーがあります。

次のコードがあります:

package p1;

public class C1 {
    protected void doIt() {}
}


package p2;

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        c1_instance.doIt(); // wtf!!!!
    }
}

エラーが発生し、それを述べています doIt() アクセスを保護しており、アクセスできません!しかし、私はサブクラスにいて、アクセスを持っています doIt() 方法。

バグではありませんか?

役に立ちましたか?

解決

私も印象を持っていました protected 「同じパッケージまたはサブクラスからアクセス可能」を意味しましたが Java言語仕様 もちろん、より正確であり、cのサブクラスsでは、「アクセスが適格名q.idである場合、qは式の名前である場合、式qのタイプの場合にのみアクセスが許可されます。 SまたはSのサブクラスです」

したがって、アクセスすることしかできません protected このように、あなたが呼んでいるサブクラスへの参照を介したスーパークラスの方法:

public class C2 extends C1 {
    private C2 c2_other_instance;
    public void doItAgain() {
        c2_other_instance.doIt();
    }
}

サブクラスの異なるインスタンスからスーパークラスの1つのインスタンスにアクセスしたい理由を説明すると、誰かがより良いデザインを提案できるかもしれません。それ以外の場合は、メソッドを作成する必要があります public または、クラスを同じパッケージに入れます。

他のヒント

Javaでは、電話することはできません protected 方法 基本クラスの別のインスタンスで, 、サブクラス内からでも:

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        doIt();             // fine
        c1_instance.doIt(); // disallowed
    }
}

唯一の例外は、基本クラスとサブクラスの両方が同じパッケージにある場合です。

引用する Java OOチュートリアル:

protected 修飾子は、メンバーが独自のパッケージ内(パッケージプライベートと同様)内でのみアクセスできることを指定し、さらに、クラスのサブクラスによって別のパッケージにアクセスできることを指定します。

保護されていることは、パッケージレベルアクセスと同等です。別のパッケージに入っている場合、メソッドにアクセスできません。

ただし、C2はサブクラスであるため、C1_Instanceオブジェクトを通過せずにDOIT()を直接呼び出すことができるはずです。

から http://download.oracle.com/javase/tutorial/java/javaoo/accesscontrol.html

「保護された修飾子は、メンバーが独自のパッケージ内(パッケージプライベートのように)内でのみアクセスできることを指定し、さらに、クラスのサブクラスが別のパッケージにあることを指定します。」

C2はC1のサブクラスかもしれませんが、これは、異なるインスタンスでこれらのメソッドにアクセスできるという意味ではありません。つまり、C1_InstanceはC2のインスタンスではない場合があります。同じパッケージにある場合は、アクセスできます。

いいえ、 protected 同じパッケージと子孫クラスにアクセスを保証します。あなたは同じパッケージにも含まれていませんし、子孫クラスから直接アクセスしていません。 C2 子孫ですが c1_instance そうではありません。

メソッドが保護されていると宣言されている場合、パッケージとサブクラス内でこのクラス内でこれにアクセスできます。

ここに質問があります。なぜこの保護されたメンバーにサブクラスからアクセスするというエラーがあるのですか。答えは、サブクラスから保護された方法にアクセスすることです。サブクラスは、直接サブクラスから直接メソッドを使用する必要があります。ここでは、直接サブクラスはC2ですが、インスタンスC1_INSTANCEはそうではありません。この方法は、c1_instance.doit()の代わりに直接(doit()を使用できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top