Overriding private methods in (non-)static classes
我有这个测试代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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"); } } } |
首先,我认为一切都是可行的:
1 2 3 4 | Overriden call to private method ---------------- 1 2 2 |
然后,如果我调用了未实现的父方法,继承类的私有方法将不起作用。可以解释为"所有私有方法都是最终的,并且隐藏在派生类中",所以
1 2 3 4 | Call to private method from parent class ---------------- 1 1 1 |
最后,在静态类中,当我调用非静态私有方法时,突然出现了一些魔力:
1 2 3 4 | Some magic ---------------- 1 2 1 |
我原以为埃多克斯在这儿。为什么我错了?
在
考虑简短的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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(); } } |
澄清。。。在我对这个答案的评论中:多态性对于访问数据字段无效,只对方法有效。考虑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
尽管
私有方法仅对声明它们的类可用,而不是该类的子级。
如果要在子类中使用父类中的方法,则必须将其设置为
在上一个例子中,您强制转换为test3,因此出于所有的意图和目的,该类认为它是test3,并调用test3的print方法。静态实例不是强制转换的(您总是用其限定名调用它们),因此它们总是调用自己的私有方法。
就像你说的,你不能重写一个