原文链接:http://zhangjunhd.blog.51cto.com/113473/19287/
class
MyObject {}
public
class
Test {
public
static
void
main(String[] args) {
MyObject obj =
new
MyObject();
obj.clone();
// Compile error.
}
}
|
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.
}
}
|
package
1
public 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.
}
}
|
|
public
|
protected
|
default
|
private
|
同类
|
T
|
T
|
T
|
T
|
同包
|
T
|
T
|
T
|
|
子类(不同包)
|
T
|
T
|
|
|
不同包中无继承关系的类
|
T
|
|
|
|
本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/19287
下面评论:
《Java in a Nutshell》对这个问题的表述也不是很清楚。虽然有举例,但没有总结哦。其实这个问题,就是一句话,那就是“与基类不在同一个包中的子类,只能访问自身从基类继承而来的受保护成员,而不能访问基类实例本身的受保护成员”。
对于示例1的解释就是——虽然MyObject与Test属于同一个包,但受保护的clone方法来自java.lang.Object类型,而在Test中,其基类Object的受保护方法是不可见的。
对于示例2的解释就是——MyObject与Test在同一个包中,受保护的clone方法来自MyObject本身,所以它对Test而言是可见的。另外在这个示例中,还说明了super关键字对于基类受保护成员的调用是个语言设计之中的“例外”。
示例3很简单了,就是企图跨越不同的包,从子类中调用基类实例的受保护方法。
最后,我在补充两个例子:
示例4:(针对示例1的修改)
class MyObject extends Test{}
public class Test {
public static void main(String[] args) {
MyObject obj = new MyObject();
obj.clone(); // Compile ok.
}
}
为什么可见呢?因为MyObject的clone方法继承自Test,而Test做为相对于Object的子类,是可以访问继承而来的属于它自己的受保护方法的~
示例5:
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.
示例6:
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!
}
}
不同包中子类本身的受保护方法当然不可能对父类可见~
再补充示例7:
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
好,这个问题就可以句号了。
已经懵圈了,先存起来吧。