[英]Sub-class not able to access the protected method of super-class when the reference is of type super-class
家長班
package p1;
public class A {
protected void display() {
System.out.println("Displayed");
}
}
兒童班(另一個包)
package p2;
import p1.A;
public class B extends A {
public static void main(String[] args) {
A a = new B();
a.display();
}
}
在子類中,如果我寫B a = new B()
,它工作正常並顯示“顯示”。
但是,在子類中上面的一段代碼,其中A a = new B()
被寫入,它會拋出編譯時錯誤,因為'display()' has protected access in 'p1.A'
我現在對受保護的訪問修飾符感到困惑,因為當引用類型是父類時它是如何工作的?
正如我在評論中所寫,你可以這樣做:
package p2;
import p1.A;
public class B extends A {
public static void main(String[] args) {
B a = new B();
a.foo();
}
public void foo() {
display(); // works
super.display(); // same, but more wordy
A a = (A)this;
a.display(); // NOT working !!!
}
public void bar(A a) {
a.display(); // NOT working !!!
}
}
display()
,可以從子類調用(靜態方法不是成員方法),也可以在同一個包中調用
package p1;
public class C {
public static void main(String[] args) {
A a = new A();
a.display();
}
}
嗯,那些
a.display(); // NOT working !!!
對我來說不是很清楚,請參閱討論
A a = new B();
不起作用,因為的引用類型a
是A
和A
不暴露display()
到另一個包。
舉個例子:
public void method(A a){ // defined in some class in a different package
a.display(); // can't be called from different package as reference type is `A`
}
這里的編譯器沒有辦法知道你是否會分配A
或一個亞型的A
,因此它撈出。
如果你忘記你的例子一秒鍾並且只關注我創建的方法會更容易理解,請注意我說它是在不同包中定義的類中。 現在問問自己,我可以從另一個包中調用A
上A
display()
,顯然不是一個受保護的方法。
以下是相關語言規范段落:
如果訪問是通過限定名稱Q.Id或方法引用表達式Q :: Id(第15.13節),其中Q是ExpressionName,則當且僅當表達式Q的類型是S或a時才允許訪問S的子類
( 6.6.2.1。訪問受保護成員 )
在你的情況下, Q
是a
, S
是B
由於Q
的類型不是B
的子類,因此不允許訪問。
有關為何引入此限制的說明,請參閱檢查Java虛擬機中受保護成員的訪問權限 (搜索受保護成員的要求 )
限制受保護訪問的動機是防止幾乎任意訪問受保護的對象成員[Yel02]。 假設m是c中聲明的受保護的非靜態字段。 沒有限制,任何類x都可以使用以下技巧讀取類c的任何對象的字段m的內容:定義c的子類s(該技巧僅在c不是final的情況下有效,因此“幾乎”副詞以上); 在s中聲明一個方法,該方法將類c的對象作為參數並返回其m字段的內容; 並讓x調用此方法。 對受保護訪問的限制可以防止這種情況,因為只有當對象的類o滿足o≤s時,s才能訪問該字段
受保護的方法只能通過包外的子類中的繼承來訪問
每個子類和同一個包中的每個類都可以訪問display 。
顯示將在同一個包中的每個類都可訪問(如果在不同的包中,則不在子類中可用)
A =新B(); 將無法工作,因為a的引用類型是A和A不會將display()暴露給另一個包。
下面的代碼將起作用:
package p2;
import p1.A;
public class B extends A {
public static void main(String[] args) {
B a = new B();
a.demo();
}
public void demo(){
display();
}
}
我想從鏈接: http : //tutorials.jenkov.com/java/access-modifiers.html重要聲明是
受保護的訪問修飾符提供與默認訪問修飾符相同的訪問權限,並且子類可以訪問超類的受保護方法和成員變量(字段)。
這里,子類僅表示子類引用類型。 對於父引用類型,剩下的唯一選項是public。
這是一種未說明的隱藏規則。 甚至IDE也建議將其更改為public以通過父級的引用進行訪問。 奇怪的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.