我正在阅读Java中的protected modifier,哪些字段可以在同一个包和子类中访问。
现在我写了一些代码。
package com;
public class Parent {
protected void print()
{
System.out.println("dFDF");
}
}
现在是子类。
package abstraact.concept;
import com.Parent;
public class BaseParent extends Parent{
public void printNum()
{
Parent p = new Parent();
p.print(); /** Getting error here */
// The method print() from the type Parent is not visible
}
public static void main(String[] args) {
BaseParent pp = new BaseParent();
pp.printNum();
}
}
为什么我收到错误? 因为可以从子类访问受保护的方法/变量。
答案 0 :(得分:7)
这是一个常见的"悖论"在Java
,这根本不是悖论。简单地说,由于语言的安全性(可见性)规则,人们无法通过另一个包中的对象引用访问受保护的方法。
声明新对象后,它具有(或允许)的可见性由代码所属的包控制,而不是由继承层次结构控制。
调用
super.print();
或
this.print();
会奏效。
答案 1 :(得分:4)
仔细尝试并理解陈述。受保护仅在派生类中可见。这对于继承来说是正确的。但是,当您创建父类型的对象时,您不使用继承。这意味着Parent不是在那里派生的,父的功能是受保护的。但是,如果使用super.print()
,它将通过继承引用Parent并获取该函数。
所以你的解决方案是替换:
Parent p = new Parent();
p.print();
带
super.print();
答案 2 :(得分:2)
致电super.print()
而不是声明新的Parent
对象
答案 3 :(得分:1)
如果包不同,则无法访问受保护的方法。您可以按如下方式访问此方法:
BaseParent pp = new BaseParent();
pp.print();
或
super.print();
答案 4 :(得分:0)
将print方法声明为protected,允许它由子类BaseParent继承。
当BaseParent中的代码引用其自己的(继承)版本的" print"时,这是允许的,因为它已成为该子类的一部分。 但是,子类仍然不能引用父类自己的方法版本(虽然在同一个包中会覆盖它),因为" protected" keyword只允许其他包中的子类继承并使用自己的方法版本。
经过一段时间的努力去理解错误出现的原因后,我就开始考虑这个问题了。
Oracle 6.6.6节http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1中的文档以自己的方式说明了这一点:
对象的受保护成员或构造函数可以从包外部访问,只能通过负责实现该对象的代码来声明该对象
因此BaseParent仅负责其自己的继承print methoid,而不是父类中的原始。