對於protected的成員或方法,要分子類和超類是否在同一個包中。
與基類不在同一個包中的子類,只能訪問自身從基類繼承而來的受保護成員,而不能訪問基類實例本身的受保護成員。
SubB has access only to the inherited from Base protected elements, i.e. its own elements, but the protecteddata of other Base
instances is not accessible from SubB
.
class
MyObject {}
public
class Test {
public static void main(String[] args) {
MyObject obj = new MyObject();
obj.clone(); // Compile error.
}
}
雖然MyObject與Test屬於同一個包,但受保護的clone方法來自java.lang.Object類型,而在Test中,其基類Object的受保護方法是不可見的。
ex2:
class
MyObject2 {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public
class Test2 {
public static void main(String[] args) throws CloneNotSupportedException {
MyObject2 obj = new MyObject2();
obj.clone(); // Compile OK.
}
}
MyObject與Test在同一個包中,受保護的clone方法來自MyObject本身,所以它對Test而言是可見的。另外在這個示例中,還說明了super關鍵字對於基類受保護成員的調用是個語言設計之中的“例外”。
ex3:
package
1
class
MyObject3 {
protected
Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package
2
public
class Test3 extends MyObject3 {
public static void main(String args[]) {
MyObject3 obj = new MyObject3();
obj.clone(); // Compile error.
Test3 tobj = new Test3();
tobj.clone();// Complie OK.
}
}
企圖跨越不同的包,從子類中調用基類實例的受保護方法。明顯不行。
ex4:
class MyObject extends Test{}
public class Test {
public static void main(String[] args) {
MyObject obj = new MyObject();
obj.clone(); // Compile ok.
}
}
public class Test {
public static void main(String[] args) {
MyObject obj = new MyObject();
obj.clone(); // Compile ok.
}
}
為什么可見呢?因為MyObject的clone方法繼承自Test,而Test做為相對於Object的子類,是可以訪問繼承而來的屬於它自己的受保護方法的。
ex5:
package 1
class MyObject extends Test {
}
package 2
public class Test {
public static void main(String args[]) {
MyObject obj = new MyObject();
obj.clone(); // Compile OK
}
}
雖然處於不同的包,但子類的受保護方法實際上繼承自父類,父類的自己的受保護方法對自己可見,其原理同示例4.
ex6:
class MyObject extends Test {
}
package 2
public class Test {
public static void main(String args[]) {
MyObject obj = new MyObject();
obj.clone(); // Compile OK
}
}
雖然處於不同的包,但子類的受保護方法實際上繼承自父類,父類的自己的受保護方法對自己可見,其原理同示例4.
ex6:
package 1
class MyObject extends Test {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package 2
public class Test {
public static void main(String args[]) {
MyObject obj = new MyObject();
obj.clone(); // Compile error!
}
}
不同包中子類本身的受保護方法當然不可能對父類可見
class MyObject extends Test {
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package 2
public class Test {
public static void main(String args[]) {
MyObject obj = new MyObject();
obj.clone(); // Compile error!
}
}
不同包中子類本身的受保護方法當然不可能對父類可見
ex7:
package a;
class MyObject extends Test {
public static void main(String[] args) {
Test test = new Test();
test.clone(); // Compile error.
}
}
package a;
public class Test {
}
同一個包中,父類實例的clone方法在子類中依然不可見,原理同示例1,就是因為父類的clone方法,實際上來自java.lang.Object。
class MyObject extends Test {
public static void main(String[] args) {
Test test = new Test();
test.clone(); // Compile error.
}
}
package a;
public class Test {
}
同一個包中,父類實例的clone方法在子類中依然不可見,原理同示例1,就是因為父類的clone方法,實際上來自java.lang.Object。