我想了解下面示例中发生的情况(通过子类从包外部访问受保护的成员) .
我知道对于包外的类,子类只能通过继承来查看受保护的成员 .
有两个包: package1
和 package2
.
package1
:ProtectedClass.java
package org.test.package1;
public class ProtectedClass {
protected void foo () {
System.out.println("foo");
}
}
package2
:ExtendsprotectedClass.java
package org.test.package2;
import org.test.package1.ProtectedClass;
public class ExtendsprotectedClass extends ProtectedClass {
public void boo() {
foo(); // This works,
// since protected method is visible through inheritance
}
public static void main(String[] args) {
ExtendsprotectedClass epc = new ExtendsprotectedClass();
epc.foo(); // Why is this working?
// Since it is accessed through a reference,
// foo() should not be visible, right?
}
}
package2
:UsesExtendedClass.java
package org.test.package2;
public class UsesExtendedClass {
public static void main(String[] args) {
ExtendsprotectedClass epc = new ExtendsprotectedClass();
epc.foo(); // CompilationError:
// The method foo() from the type ProtectedClass
// is not visible
}
}
据了解, ExtendsprotectedClass
中的 boo()
方法可以访问 foo()
,因为受保护的成员只能通过继承访问 .
我的问题是,为什么 foo()
方法在 ExtendsprotectedClass
的 main()
方法中通过引用访问时工作正常,但在通过 UsesExtendedClass
中的 epc
引用访问时不起作用?
4 回答
允许
ExtendsprotectedClass
类中的代码通过ExtendsprotectedClass
类型的引用访问ProtectedClass
的受保护成员 . 来自JLS section 6.6.2:和
UsesExtendedClass
对于ExtendsprotectedClass
的实现不负责任,因此最终调用失败 .编辑:这背后的原因是
protected
访问旨在帮助子类实现他们需要的功能,从而提供比通常可用的超类内部更多的访问权限 . 如果所有代码都可以使用它,那么将该方法公之于众 . 基本上,子类被信任不破坏封装;他们公开了这些细节,但受保护的API只能用于为子类提供更多机会 .它在第一种情况下工作,因为它是从同一个类调用的,即使通过引用访问该方法也是如此 . 您甚至可以通过同一主方法中的引用调用
ExtendsprotectedClass
的private
方法 .我相信你已经回答了自己的问题; UsesExtendedClass不从ProtectedClass继承,并且 - 根据定义 - “protected”成员只能在声明/定义它们的类中或在继承自声明或定义它们的类中访问 .
看看这张照片来自:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
很明显,类的受保护成员可以通过子类访问 .