[英]Java : Protected access restriction for subclass on superclass object
我知道之前在這個論壇上有人問過這個問題,但我會再問一次,因為我沒有看到任何好的答案(到目前為止)。
它是這樣的:
package a;
public class A{
protected int a;
}
package b;
public class B extends A{
}
package c;
public class C extends B{
public void accessField(){
A ancient = new A();
ancient.a = 2; //A - That wouldn't work.
a = 2; //B - That works.
}
}
為什么 A) 條款不起作用? 子類 C 中對超類對象古代訪問的這種限制背后的原因是什么?
謝謝。
受保護的成員只能在同一個包之外通過繼承訪問——即在層次結構內。
因此,當您從不同的包創建 A 的另一個實例時,這不是繼承關系,因此會失敗。
與往常一樣,這在 JLS 6.6.2 中有介紹:
對象的受保護成員或構造函數可以從包外部訪問,在該包中僅由負責實現該對象的代碼聲明它。
實際上,您不需要兩級繼承,下面的代碼會導致相同的行為:
public class B extends A{
public void accessField() {
A ancient = new A();
ancient.a = 2; //A - That wouldn't work.
a = 2; //B - That works.
}
}
a = 2
工作的原因是JLS 6.2.2.1 :
設 C 是聲明受保護成員的類。 只允許在 C 的子類 S 的主體內訪問。
請注意,它沒有說直接子類,而只是說子類。 所以a = 2
在B
類或C
類中工作。
另一方面, ancient.a = 2;
包含在同一部分的下一個要點中:
如果訪問是通過限定名稱 Q.Id 進行的,其中 Q 是 ExpressionName,那么當且僅當表達式 Q 的類型是 S 或 S 的子類時才允許訪問。
在你的情況, Q.Id
是ancient.a
=>那只如果訪問的類型ancient
是B
或子類B
。 例如,這將編譯:
public class B extends A{
public void accessField() {
C ancient = new C();
ancient.a = 2; //A - That wouldn't work.
}
}
引自 The Java Programming Language 3 ed 一書。 作者:Gosling 等人 - 第 81 頁 3.5
“受保護的真正含義” - .. 除了可以在類本身中訪問以及在同一個包中進行編碼之外,還可以通過與類至少具有相同類型的對象引用從類訪問受保護成員 - 即類的類型或其子類之一的引用
對象的受保護成員或構造函數可以從包外部訪問,在該包中僅由負責實現該對象的代碼聲明它。
當你說,
A ancient = new A();
ancient.a = 2;
您沒有從古代(一個對象)繼承任何東西,因此不對其實現負責。 通過使C 擴展 A ,您已經從不同的 A 對象繼承了 'a',因此下面的語句有效。
a = 2;
如果,
ancient.a = 2;
有效,那么公共和私有訪問說明符之間沒有區別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.