package pack1;
class A{
protected void m1(){
System.out.println("protected modifier");
}
}
package pack2;
class B extends A{
public static void main(string[]args){
B b = new B();//Valid
b.m1();
A a = new B();//Invalid
a.m2();
A a1 = new A();//InValid
a1.m1();
}
}
为什么在访问包外的受保护成员时,我们只需要引用子类即可?
为什么我们不能使用父引用来访问受保护的成员(这里A a = new B())?
我浏览了博客和许多堆栈溢出答案,但是找不到任何答案。
所以有人可以帮助我知道为什么的答案吗?
最佳答案
不允许您访问A
,因为您仍然不在子类或包中。 main
方法是static
,因此不受B
类实例的约束。为了访问A
,您需要位于B
类中,因此在非静态上下文中,例如
public class B extends A {
public void foo() {
m1(); // Valid call since inside subclass
}
}
我认为您误解了
static
的含义。protected
的详细信息在Java语言规范中进行了描述。从JLS§6.6.2中摘录:对象的
protected
成员或构造函数可以从仅由负责该对象实现的代码声明的包外部访问。假设
C
是声明protected
成员的类。仅在S
的子类C
的主体内允许访问。限制甚至超出了您的示例。关键是“负责实施”。将其与以下示例进行比较:
package a;
public class Point {
protected int x;
protected int y;
}
package b;
import a.Point;
public class Point3D extends Point {
public void delta(Point other) {
other.x += this.x; // Compile-time error: Cannot access other.x
other.y += this.y; // Compile-time error: Cannot access other.y
}
}
尽管类
Point3D
是Point
的子类,但它不负责other
对象的实现。因此,不允许访问其protected
成员。相同的
public class B extends A {
public void foo() {
A other = new A();
other.m1(); // Compile-time error
}
}
因为
foo()
方法调用所属的当前实例不负责other
的实现。因此,不允许访问。