Java:跨包的受保护访问
我想了解下面的示例中发生的情况(其中通过子类从包外部访问受保护的成员)。
我知道对于包外的类,子类只能通过继承才能看到受保护的成员。
有两个包:package1
和 package2
。
package1
:ProtectedClass.java
package org.test.package1; 公共类受保护类{ 受保护的无效foo(){ System.out.println("foo"); } }
package2
:ExtendsprotectedClass.java
< /p>package org.test.package2; 导入 org.test.package1.ProtectedClass; 公共类 ExtendsprotectedClass 扩展 ProtectedClass { 公共无效嘘(){ foo(); // 这有效, // 因为受保护的方法通过继承可见 } 公共静态无效主(字符串[] args){ ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // 为什么这个有效? // 由于它是通过引用访问的, // foo() 不应该是可见的,对吧? } }
package2
:UsesExtendedClass.java
< /p>package org.test.package2; 公共类使用扩展类{ 公共静态无效主(字符串[] args){ ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // 编译错误: // ProtectedClass 类型的 foo() 方法 // 不可见 } }
据了解,是ExtendsprotectedClassboo()
方法code> 可以访问 foo()
,因为受保护的成员只能通过继承来访问。
我的问题是,为什么当通过 ExtendsprotectedClass
的 main()
方法中的引用访问时,foo()
方法工作正常,但是 通过 UsesExtendedClass
中的 epc
引用访问时无法工作?
I would like to understand what's happening in the example below (where a protected member is being accessed from outside the package through a subclass).
I know for classes outside the package, the subclass can see the protected member only through inheritance.
There are two packages: package1
and 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 } }
It is understood that the boo()
method in ExtendsprotectedClass
can access foo()
, since protected members can be accessed through inheritance only.
My question is, why is the foo()
method working fine when accessed through a reference in the main()
method of ExtendsprotectedClass
but will not work when accessed through the epc
reference in UsesExtendedClass
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看看这张图片:http://docs.oracle。 com/javase/tutorial/java/javaOO/accesscontrol.html
很明显受保护的成员类的内容可以通过子类来访问。
take a look on this picture from : http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
its clear that protected member of class can be accessed via subclass.
我相信你已经回答了你自己的问题; UsesExtendedClass 不继承自 ProtectedClass,并且根据定义,“受保护”成员只能在声明/定义它们的类中或从声明或定义它们的类继承的类中访问。
I believe you've answered your own question; UsesExtendedClass does not inherit from ProtectedClass, and -- by definition -- "protected" members are accessible only in the class in which they are declared / defined or in a class that inherits from the one in which they are declared or defined.
它在第一种情况下工作,因为它是从同一个类调用的,即使该方法是通过引用访问的。您甚至可以通过同一主方法中的引用来调用
ExtendsprotectedClass
的private
方法。It is working in the first case because it is being called from the same class even the method is being accessed through a reference. You could even call a
private
method ofExtendsprotectedClass
through a reference in the same main method.允许
ExtendsprotectedClass
类中的代码通过ExtendsprotectedClass
类型的引用访问ProtectedClass
的受保护成员。来自 JLS 第 6.6.2 节 :和
UsesExtendedClass
不负责ExtendsprotectedClass
的实现,因此最终调用失败。编辑:这背后的原因是受保护的访问旨在帮助子类实现它们所需的功能,从而提供比通常可用的更多对超类内部的访问权限。如果这对所有代码都可用,那么就非常接近将该方法公开了。基本上,子类被信任不会破坏封装;他们在自己类型的对象中被赋予了更多功能。公共API不应该公开这些细节,但受保护的API可以只是为了给子类更多的机会。
Code within the
ExtendsprotectedClass
class is allowed to access protected members ofProtectedClass
via a reference of typeExtendsprotectedClass
. From the JLS section 6.6.2:and
UsesExtendedClass
isn't reponsible for the implementation ofExtendsprotectedClass
, hence the final call fails.EDIT: The reasoning behind this is that
protected
access is designed to help subclasses implement the functionality they need, giving more access to the internals of the superclass than would normally be available. If that were available to all code, it would be pretty close to making the method public. Basically, the subclasses are trusted not to break encapsulation; they're given more capabilities within objects of their own type. The public API shouldn't expose those details, but the protected API can just for the purposes of giving subclasses more opportunities.