我有这个测试代码示例:
public class Test { private static class Test3 { private void print1() { System.out.println("1"); } } private static class Test4 extends Test3 { private void print1() { System.out.println("2"); } } public static void main(String[] args) { System.out.println("Overriden call to private method ----------------"); OuterTest.Test1 test1 = new OuterTest.Test1(); OuterTest.Test2 test2 = new OuterTest.Test2(); OuterTest.Test1 test12 = new OuterTest.Test2(); test1.invokeOverriden(); test2.invokeOverriden(); test12.invokeOverriden(); System.out.println("Call to private method from parent class ----------------"); test1.invokeNotOverriden(); test2.invokeNotOverriden(); test12.invokeNotOverriden(); System.out.println(" Some magic ----------------"); Test3 test3 = new Test3(); Test4 test4 = new Test4(); Test3 test34 = new Test4(); test3.print1(); test4.print1(); test34.print1(); } } class OuterTest { public static class Test1 { public void invokeOverriden() { print1(); } public void invokeNotOverriden() { print1(); } private void print1() { System.out.println("1"); } } public static class Test2 extends Test1 { @Override public void invokeOverriden() { print1(); } private void print1() { System.out.println("2"); } } }
首先,我认为它应该起作用:
Overriden call to private method ---------------- 1 2 2
然后,如果我调用了非实现的父方法,则继承类的私有方法消失。它可以解释为"所有私有方法都是最终的并且隐藏在派生类中#34;所以invokeNotOverriden()
对Test2类中的方法一无所知:
Call to private method from parent class ---------------- 1 1 1
最后,在静态类中,当我调用非静态私有方法时,会突然出现一些魔法:
Some magic ---------------- 1 2 1
我在这里预计1 2 2
。为什么我错了?
答案 0 :(得分:2)
你在1 2 1
部分得到some magic
,因为私有方法没有多态性解析,编译器创建对包含在声明的类型变量中的方法的调用,在你的情况下Test3
。在print1
中将Test3
声明为非私有(因此,在Test4
中,因为它禁止收紧方法的访问修饰符)并查看操作中的多态,因此您将获得预期{ {1}}。
考虑更短的例子:
1 2 2
澄清 ...对我对此答案的评论:多态性对于访问数据字段无效,仅适用于方法。考虑:
class Test {
private static class Test3 {
private void print1() {
System.out.println("non-polymorphic 1");
}
void polymorphic() {
System.out.println("polymorphic 1");
}
}
private static class Test4 extends Test3 {
private void print1() {
System.out.println("non-polymorphic 2");
}
void polymorphic() {
System.out.println("polymorphic 2");
}
}
public static void main(String[] args) {
Test4 t4 = new Test4();
t4.print1();
t4.polymorphic();
System.out.println("======");
Test3 t34 = new Test4();
t34.print1();
t34.polymorphic();
}
}
尽管private static class Test3 {
int i = 1;
}
private static class Test4 extends Test3 {
int i = 2;
}
public static void main(String[] args) {
Test4 t4 = new Test4();
System.out.println(t4.i);
System.out.println("======");
Test3 t34 = new Test4();
System.out.println(t34.i);
}
已声明为非私有,但i
值为t34.i
。
答案 1 :(得分:1)
私有方法仅适用于声明它们的类,而不是该类的子类。
如果您希望在子级中使用父级的方法,则必须将其设为protected
。
在你的最后一种情况下,你已经转换为Test3,所以对于所有意图和目的,该类认为它是Test3并调用Test3的print方法。静态实例不会被强制转换(您总是使用其限定名称调用它们),因此它们总是调用自己的私有方法。
答案 2 :(得分:0)
就像你说的那样,你无法覆盖private
方法,将其设为protected