被protected修饰的成员对于本包和其子类可见
这句话容易产生误解
我们实际通过代码来看:
Father1 和 Test1 在同一个包
Son1和Father1在同一个包
Son2和Father1不在同一个包
因为protected的作用范围是本包以及不同包下的子类可见
因此 son2可以成功调用play方法
但是:
Father1 和 Test2 不在同一个包时
即使Son1和Son2是Father1的子类
但并没有访问play方法的权限:
所以这里对 被protected修饰的成员对于本包和其子类可见
这句话经常会产生误解
既然Son1和Son2是Father1的子类,
那为什么在Test2中不能访问呢?
问题的关键在于Test2:
Test2既和Fater1不在同一个包下,
又和Father1不是继承关系
因此即使 Son1和Son2是Father1的子类,
Test2也无法访问别的子类实例所继承的protected修饰的方法
那如果这样说,又会产生一个问题
我让Test2继承Father1,
那么Son1和Son2的实例在Test2中能否访问play方法呢?
答案是不行:
那再回头来看,
若Test2继承Father1
它自己的实例是完全可以访问play方法的:
因为虽然不同包,但被protected修饰的成员对其子类(Test2)可见
所以对被protected修饰的成员对于本包和其子类可见这句话可以进行如下补充
若子类与父类不在同一包中 (翻译:当Test2和Fater1不在同一个包中,但是Test2此时是Father1的子类)
子类只能在自己的类(域)中访问父类继承而来的protected成员
(翻译:Test2可以访问自己的父类play方法)
无法访问别的子类实例(即便同父类的亲兄弟)所继承的protected修饰的方法
(翻译:无法访问Son1,Son2这些别的子类实例,即便它们和Test2一样继承的都是Father1的父类方法,play方法)
Object中的clone方法
现在我们来看Object中被project修饰的clone方法:
此时在一个Test类中,
创建一个Student类对象,
在调用clone方法时可能会陷入到这样的思维误区中:
既然Object类是所有类的父类
protected的作用范围又是本包或它的子类可见
那应该是Student类对象可以直接调用clone方法的
但经过刚才我们自己的梳理,
student类虽然是Obejct的子类
但此时在Test类中
它是不能访问 别的子类实例(即便同父类的亲兄弟)所继承的protected修饰的方法的
所以student无法直接访问clone方法,只能重写(或者是在自己的本类中调用):
要么是在Test中
new Test的对象
test对象可以访问clone方法:
从而我们可以更好地理解
为什么Object类中clone()方法要被protected修饰
Object类中clone()方法声明为protected是一种保护机制,
他的目的是在类中未重写Object的clone()方法的情况下,
只能在本类里才能“克隆”本类的对象。
对protected的理解只是简单粗浅地进行了解释,可参考其他文章,做更为细致地思考: