2013-06-12 105 views
6

我想對此進行一些討論,但我無法推斷出我的案例的答案。仍然需要幫助。Java:無法訪問擴展子類中超類的受保護成員

這裏是我的代碼:

package JustRandomPackage; 

public class YetAnotherClass{ 
    protected int variable = 5; 
} 
package FirstChapter; 

import JustRandomPackage.*; 

public class ATypeNameProgram extends YetAnotherClass{ 
    public static void main(String[] args) { 

     YetAnotherClass bill = new YetAnotherClass(); 
     System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible 

    } 
} 

一些定義以下其中,上面的例子似乎是混亂:

1. Subclass is a class that extends another class. 
2. Class members declared as protected can be accessed from 
    the classes in the same package as well as classes in other packages 
    that are subclasses of the declaring class. 

問題:爲什麼不能我訪問來自子類YetAnotherClass實例()的受保護成員(int variable = 5)對象)?

+1

問題是什麼? –

回答

3

作爲聲明類的子類的其他包中的類只能訪問自己繼承的protected成員。

public class ATypeNameProgram extends YetAnotherClass{ 
    public ATypeNameProgram() { 
     System.out.println(this.variable); // this.variable is visible 
    } 
} 

...但不是其他對象的繼承protected成員。

public class ATypeNameProgram extends YetAnotherClass{ 
    public ATypeNameProgram() { 
     System.out.println(this.variable); // this.variable is visible 
    } 

    public boolean equals(ATypeNameProgram other) { 
     return this.variable == other.variable; // error: YetAnotherClass.variable is not visible 
    } 
} 
+0

這是錯誤的。此代碼編譯。另一個包中的類只能訪問與類本身具有相同類型的繼承保護成員。 –

1

賬單不是子類YetAnotherClass的一部分。賬單是一個單獨的YetAnotherClass。

嘗試int bill = this.variable;(在構造函數中)訪問子類的成員。

0

您未創建擴展它的類的實例,而是創建父類的實例。檢查下面的代碼:

public class ATypeNameProgram extends YetAnotherClass{ 
    public static void main(String[] args) { 

     YetAnotherClass bill = new YetAnotherClass(); 
     System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible 

     ATypeNameProgram a = new ATypeNameProgram(); 
     System.out.println(a.variable); //this will work 

    } 
} 
1

您的代碼將工作,如果YetAnotherClass將在同一個包ATypeNameProgram。正如其他人寫的,在其他情況下不起作用。這是一個工作示例。

package my.example; 

public class MainClass extends MyAnotherClass { 
    public static void main(String[] args) { 
     MyAnotherClass bill = new MyAnotherClass(); 
     System.out.println(bill.value); // this will work 
    } 
} 

package my.example; 

public class MyAnotherClass { 

    protected int value = 5; 

} 
1

Foo只能訪問Bar類型的保護實例成員當且僅當Bar是分配給Foo。也就是說,如果我們可以這樣寫:

Foo foo = new Bar(); 

例如,假設我們有:

package a; 

public class Base { 
    protected int protectedField; 
} 

然後我們就可以有這樣的:

package b; 

import a.Base; 

public class Parent extends Base { 
    void foo() { 
     int i = this.protectedField; 
    } 
    void foo(Parent p) { 
     int i = p.protectedField; 
    } 
    void foo(Child c) { 
     int i = c.protectedField; 
    } 
} 

class Child extends Parent { } 

這將編譯,因爲所有protectedField s的訪問通過Parent的實例。請注意,因爲Parent引用可以是Child實例(即我們可以編寫Parent p = new Child();),所以我們可以訪問c.protectedField

下面就編譯:

package b; 

import a.Base; 

public class Parent extends Base { 
    void foo(Stepchild sc) { 
     int i = sc.protectedField; // ERROR 
    } 
} 

class Stepchild extends Base {} 

因爲Stepchild實例不是Parent一個實例。

有點混亂,這不會編譯之一:

package b; 

import a.Base; 

public class Parent extends Base {} 

class Child extends Parent { 
    void foo(Parent p) { 
     p.protectedField; // ERROR 
    } 
} 

這是因爲Parent對象不是Child一個超類或超等Child無法訪問其protected成員。

如果您遇到過難以記憶的問題,只要考慮是否可以將該類型寫入類的引用類型即可。例如,我們可以這樣寫:

Parent p = new Child(); 

但不能寫入

Child c = new Parent();  // ERROR 
Parent p = new Stepchild(); // ERROR 

所以Child將無法​​獲得Parent的保護成員,Parent將無法​​獲得Stepchild的保護成員。

一對夫婦的最後一站:

記住protected訪問允許包中的知名度。根據我的經驗,人們會忘記這一點。

最後,protected static成員在繼承層次結構中始終可見。

相關問題