2012-10-12 80 views
5

我對保護標識符有些疑惑。在K.Sierra的Sun認證的Java程序員學習指南的第一章中,我發現了以下信息:受保護的成員行爲一旦被繼承。

「一旦子包外部的包繼承了受保護的成員,該成員(由子類繼承)對子類外的任何代碼都是私有的,除了子類的子類之外。「

我提供了反映上述說明的示例代碼,這對我來說是絕對清楚的。

// 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」 變量,它是一個有點令人驚訝的對我來說,因爲它不符合聲明「變爲私有的子類以外的任何代碼」

- >但你在包package1哪個是真的根據"Protected members can be accessed by classes in same package"

「移動Neighbour類一旦子類外的封裝繼承了保護構件,該構件(如繼承由子類)對子類外的任何代碼都是私有的,除了子類的子類之外。「

- >內部包仍然受到保護,並且對於包內的所有類都不是私有的。

+1

+1 - 解釋爲什麼OP觀察到的行爲與K.Sierra的書實際上*一致*。 –

1

protected可見性包括包級別可見性。 繼承允許您將您的Child對象視爲Parent的實例。 由於Parent的成員i在相同的包中聲明,因此可從Neighbour訪問。

package package1; 

import package2.Child; 

public class Neighbour { 

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