6

保護された識別子に関していくつか疑問があります。K.SierraによるSunCertifiedJava Programmer Study Guideの最初の章で、次の情報を見つけました。

「パッケージ外のサブクラスが保護されたメンバーを継承すると、そのメンバー(サブクラスによって継承される)は、サブクラスのサブクラスを除いて、サブクラス外のすべてのコードに対してプライベートになります。」

上記のステートメントを反映したサンプルコードを提供しましたが、それは私には絶対に明らかです。

// Parent class
package package1;

import package2.Child;
public class Parent {

    protected int i = 5;

}

// Child class
package package2;

import package1.Parent;

public class Child extends Parent {

    // variable 'i' inherited

}


package package2;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // no access
    }
}

私は実験を開始し、小さな変更を加えました-Neighborをpackage1に移動しました。そして、「i」変数へのアクセスがあります。これは、 「サブクラス外のコードに対してプライベートになる」というステートメントに準拠していないため、私にとっては少し驚くべきことです。

変更後のネイバークラス:

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting(){
        Child child = new Child();
        System.out.println(child.i); // access!
    }
}

はっきりさせてください。ありがとう。

4

4 に答える 4

5

つまり、protectedパッケージプライベートであるだけでなく、サブクラスにも表示されます。JLSでさえこれについて曖昧です(JLS§6.6.2):

オブジェクトのprotectedメンバーまたはコンストラクターは、そのオブジェクトの実装を担当するコードによってのみ宣言されているパッケージの外部からアクセスできます。

パッケージの外部では、サブクラスのみが保護されたメンバーにアクセスできることを指定します。これは、パッケージ内の変数にもアクセスできることを意味します。言い回しは貧弱ですが、それでも、保護されたメンバーにはパッケージレベルの可視性サブクラスレベルの可視性があります。

参照:

于 2012-10-12T15:07:11.123 に答える
3

そして、「i」変数へのアクセスがあります。これは、「サブクラス外のコードに対してプライベートになる」というステートメントに準拠していないため、私にとっては少し驚くべきことです。

Neighbour->しかし、あなたはパッケージpackage1内のクラスを移動しました。"Protected members can be accessed by classes in same package"

「パッケージ外のサブクラスが保護されたメンバーを継承すると、そのメンバー(サブクラスによって継承される)は、サブクラスのサブクラスを除いて、サブクラス外のすべてのコードに対してプライベートになります。」

->パッケージ内ではまだ保護されており、パッケージ内のすべてのクラスに対してプライベートではありません。

于 2012-10-12T15:07:30.797 に答える
1

真実は「SunCertifiedJavaProgrammer Study Guide」ではなく、Java言語仕様にあります

6.6.2。保護されたアクセスの詳細

オブジェクトの保護されたメンバーまたはコンストラクターは、そのオブジェクトの実装を担当するコードによってのみ宣言されているパッケージの外部からアクセスできます。

于 2012-10-12T15:05:51.343 に答える
1

protected可視性には、パッケージレベルの可視性が含まれます。Child継承により、オブジェクトをのインスタンスとして扱うことができますParent。のメンバーiParent同じパッケージで宣言されているため、からアクセスできますNeighbour

package package1;

import package2.Child;

public class Neighbour {

    public void protectedTesting() {
        Parent neighboured = new Child();
        System.out.println(neighboured.i); // access
    }
}
于 2012-10-12T15:33:05.533 に答える