【发布时间】:2014-06-17 22:12:48
【问题描述】:
我知道 package-private(默认)修饰符应该为每个类隐藏一个方法(或成员),但同一个包中的那些除外。但是,我发现此访问级别存在一些问题。
考虑以下代码:
// pack1/MyBaseClass.java
package pack1;
public class MyBaseClass {
/* package private */ void someMethod() {
System.out.println("MyBaseClass.someMethod");
}
}
// pack1/MyDerivedClassFromOtherPackage.java
package pack1;
import pack2.MyDerivedClassInAnotherPackage;
public class MyDerivedClassFromOtherPackage extends MyDerivedClassInAnotherPackage {
@Override
/* package private */ void someMethod() {
System.out.println("MyDerivedClassFromOtherPackage.someMethod");
// super.someMethod(); // can't compile
}
}
//pack2/MyDerivedClassInAnotherPackage.java
package pack2;
import pack1.MyBaseClass;
public class MyDerivedClassInAnotherPackage extends MyBaseClass {
// @Override // can't do this (compile error)
/* package private */ void someMethod() {
System.out.println("MyDerivedClassInAnotherPackage.someMethod");
}
}
所以基本上包 pack1 中有一个带有包私有方法 (MyBaseClass) 的基类。 pack2 中的另一个类(MyDerivedClassInAnotherPackage)扩展了 MyBaseClass,它不能覆盖包私有方法(到目前为止还可以:包私有方法只能在同一个包中访问)。
但是,pack1 中的另一个类扩展了 pack2.MyDerivedClassInAnotherPackage,这一次它可以覆盖它的包私有方法(但它不能调用super.someMethod())。
另一个奇怪的事情是 someMethod 对pack1.MyDerivedClassFromOtherPackage 表现出多态性,但对pack2.MyDerivedClassInAnotherPackage 却不是。下面的代码应该清楚我的意思:
package pack1;
import pack2.MyDerivedClassInAnotherPackage;
public class MainClass {
public static void main(String[] args) {
MyBaseClass bc = new MyBaseClass();
bc.someMethod();
System.out.println("-------------------------------------------------");
MyBaseClass otherpack = new MyDerivedClassInAnotherPackage();
otherpack.someMethod();
System.out.println("-------------------------------------------------");
MyBaseClass samepack = new MyDerivedClassFromOtherPackage();
samepack.someMethod();
System.out.println("-------------------------------------------------");
}
}
输出:
MyBaseClass.someMethod
-------------------------------------------------
MyBaseClass.someMethod
-------------------------------------------------
MyDerivedClassFromOtherPackage.someMethod
-------------------------------------------------
与这些行为相关的问题:
1. How come that pack1.MyDerivedClassFromOtherPackage is allowed to override the (package-private) method of pack2.MyDerivedClassInAnotherPackage?
2. In spite of this, why is it not possible to call super.someMethod() from pack1.MyDerivedClassFromOtherPackage?
3. Why is the class in the same package (pack1) behaving polymorphically and the one in the other package (pack2) not?
PS1.:我知道我应该一次在 SO 上发布一个问题,但我觉得这三个问题在某种程度上必须具有相同的根本原因。 (我怀疑实际上 pack1.MyDerivedClassFromOtherPackage.someFunction 覆盖了 pack1.MyBaseClass.someFunction 而不是 pack2.MyDerivedClassInAnotherPackage.someFunction。但这仍然不能解释第二个问题,而且我无法确认。)
PS2.:对于这种情况,我没有任何真正的用例。我只是在玩一些极端案例(为 OCA 考试做准备)。
【问题讨论】:
-
您是否尝试过使用
public修饰符覆盖 pack2.MyDerivedClassInAnotherPackage 中的 someMethod? -
@broncoAbierto:我不明白你的建议。如果我这样做,它将如何帮助我理解包私有(默认)访问级别的行为。 (这是问题的目的。)
-
我的猜测是你不能覆盖,因为通过声明它对 pack2-package 私有的可见性,你限制了它的可访问性。
-
@RKC:感谢您的改进。不过我不明白最后一个:你为什么把我的问题写成代码?
-
@broncoAbierto:好的,但是为什么它让我把覆盖注释放在上面呢? (见第一个问题。)
标签: java