2012-10-12 11 views
5

私は保護された識別子に関するいくつかの疑問を持っています。継承された後の保護されたメンバの動作。

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

私は上記の記述を反映したサンプルコードを提供しました。それは私にはっきりと分かります。

// 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 
    } 
} 

私は実験を開始し、小さな変更を加えました。近隣をpackage1に移動しました。

:そして、変更後の

近隣クラス「サブクラス外のコードにプライベートになり、」「i」は、それが声明に従わないとして私のために少し驚くべきことである変数がへのアクセスがあります

package package1; import package2.Child; public class Neighbour { public void protectedTesting(){ Child child = new Child(); System.out.println(child.i); // access! } } 

私にそれを明確にしてください。ありがとう。

答えて

5

簡潔に言えば、protectedは、パッケージプライベートであり、サブクラスに対しても可視です。 JLSこの(JLS §6.6.2)に曖昧である:オブジェクトの

protected部材又はコンストラクタは、そのオブジェクトの実装を担当して、それが唯一のコードで宣言されているパッケージの外側からアクセスすることができます。

パッケージ外では、サブクラスだけが保護されたメンバーにアクセスできることを指定しています。このは、を意味し、パッケージ内の変数にアクセスすることもできます。貧弱な表現ですが、保護されたメンバーはパッケージレベルの可視性とサブクラスレベルの可視性を持っています。

参照:

+0

詳細解説。 – MrKiller21

1

真実は、 "Sun認定のJavaプログラマー研究ガイド" ではなく、Java Language Specification

6.6.2ではありません。保護されたアクセスの詳細

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

+0

SCJPSGが確定していないのは事実です。しかし、それは間違っていません。 Nandkumar Tekaleの答えを参照してください。 –

+0

"パッケージ外のサブクラスが保護されたメンバを継承すると、(サブクラスによって継承された)そのメンバがサブクラスの外部にある任意のコードになります" - 個人的に、誤解を招き誤解を招きます。 – MrKiller21

3

そしてそれとして私のために少し驚くべきことである "i" の変数へのアクセスがあります「サブクラス外のコードに対して非公開になる」ステートメントに従わない

- >しかし、あなたは、サブクラス-外パッケージは、(サブクラスによって継承される)保護されたメンバー、そのメンバーを継承したら」"Protected members can be accessed by classes in same package"

に従って真実であるパッケージpackage1でクラスNeighbourを移動サブクラスのサブクラスを除いて、サブクラスの外のコードに対してプライベートになります。 "

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

+1

+1 - OPによって観察された挙動がK.Sierraの本と実際に一致している理由を説明するため。 –

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 
    } 
} 
関連する問題