我学到的一件事是java中的private
并不意味着与C ++中的相同。 java中的private
是基于类的,而不是基于对象的。
即我可以使用“对象点符号”直接访问另一个对象私有成员,前提是我在该对象的类中这样做。
然而,protected
并不是那么清楚。
我们必须在此处考虑两个包:pack1
和pack2
我们在Alpha
包中声明了类Beta
和pack1
并声明AlphaSub
扩展Alpha
pack1
,Gamma
扩展Alpha
pack2
}> 。
!
以下是类代码,我在此处仅包含与问题相关的类:Alpha
,AlphaSub
和Gamma
package pack1;
public class Alpha{
private int alphaPrivate;
public int alphaPublic;
protected int alphaProtected;
int alphaPP;
protected int alphaProtected(){
return 1;
}
private int alphaPrivate(){
return 1;
}
}
package pack2;
import pack1.Alpha;
public class AlphaSub extends Alpha{
int alphasubPP;
private int alphasubPrivate;
protected int alphasubProtected;
public int alphasubPublic;
public void meth() throws CloneNotSupportedException{
new AlphaSub().alphaProtected(); //OK
new Gamma().alphaProtected(); /*COMPILE ERROR. */
}
}
显然即使AlphaSub和Gamma都从alphaProtected()
继承Alpha
,也无法从AlphaSub调用Gamma继承的alphaProtected()
。
如果这样的情况是只能从该类中调用类的受保护方法,那么调用clone
[来自Object
类的每个类继承的{{1}}是不可能的?
有人可以澄清一下吗?
答案 0 :(得分:1)
JLS 6.6.2.1.中涵盖了您所体验到的内容:
6.6.2.1。访问受保护的会员
设C是声明受保护成员的类。访问是 只允许在C的子类S的主体内使用。
此外,如果Id表示实例字段或实例方法,则:
如果访问是通过限定名称Q.Id或方法引用表达式Q :: Id(第15.13节),其中Q是ExpressionName,那么 当且仅当表达式Q的类型是S时才允许访问 或S的子类。
如果访问是通过字段访问表达式E.Id,或方法调用表达式E.Id(...),或方法引用表达式E :: Id,其中E是主表达式(第15.8节),然后是访问权限 当且仅当E的类型是S或S的子类时才被允许。
如果访问是通过方法引用表达式T :: Id进行的,其中T是ReferenceType,那么当且仅当 type T是S或S的子类。
你是对的,如果你用new Gamma().alphaProtected();
替换new Gamma().clone();
,你将得到相同的编译错误。