我目前正在阅读SCJP学习指南。在第1章第36页中,它被提及为:
一旦子类外包继承受保护的成员, 该成员(由子类继承)变得对外部任何代码都是私有的 子类,子类的子类除外。所以如果是邻居类 实例化一个Child对象,即使类Neighbor与同一个包在同一个包中 class Child,class Neighbor无法访问Child的继承(但受保护) 变量x。
但是每当我试图通过以下代码检查时:
//parent class in pkg#1:
package com.main.parentPkg;
public class ParentInSamePkg {
protected void methodInParent(){
System.out.println("Inside ParentInSamePkg-->methodInParent");
}
}
// First child class in pkg#2
package com.main.childPkg;
import com.main.parentPkg.ParentInSamePkg;
public class ChildInOtherPkg extends ParentInSamePkg{
void mthd(){
System.out.println("inside ChildInOtherPkg:mthd");
methodInParent();
}
}
//Child class of child class inside pkg#3
package com.main.grandChildPkg;
import com.main.childPkg.ChildInOtherPkg;
class GrandChild extends ChildInOtherPkg{
void mthd(){
System.out.println("inside GrandChild:mthd");
methodInParent();
}
public static void main(String[] args) {
GrandChild g=new GrandChild();
g.mthd();
}
}
每当我执行上面的代码并运行GrandChild类的main方法时,它会将输出打印为:
inside GrandChild:mthd Inside ParentInSamePkg-->methodInParent
因此,我很困惑。根据概念,受保护的成员在子类中继承后变为私有,并且任何扩展此子类的类都无法访问此成员。但在上面的代码中,它是可访问的。
请帮助我理解。
答案 0 :(得分:1)
下表清楚地描述了所有类型的访问修饰符的行为。says here
如果受到保护,它只能由不同包中存在的非子类访问。我们可以说受保护的行为就像私有,如果只有它们被非子类访问不同的包装。
答案 1 :(得分:0)
“受保护成员[...]变成私人”的整个概念听起来很奇怪。
虽然Java语言规范通常非常难以阅读,但它实际上说的很好:
<强> 6.6.2. Details on protected Access 强>
对象的
getInputArguments()
成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明它。
重要的部分是负责实施部分。所有子类,子子类,子子类......都负责实现对象,因此他们都可以访问该成员。
这不管是它自己的实例(protected
)还是其他实例,只要它是包含代码的类的实例。
或者,正如JLS接着说:
<强> 6.6.2.1. Access to a
protected
Member 强>设C为声明
this
成员的类。只允许在C的子类S的主体内访问。此外,如果 Id 表示实例字段或实例方法,则:
如果访问权限是限定名
protected
,其中Q.Id
是 ExpressionName ,那么当且仅当类型为表达式Q
是Q
或S
的子类。如果访问是通过字段访问表达式
S
进行的,其中E.Id
是主要表达式,或者是方法调用表达式E
,E.Id(. . .)
是主要表达式,当且仅当E
的类型为E
或S
的子类时才允许访问}。