问题描述
我有这个测试代码示例:
I have this test code example:
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");
}
}
}
首先,我认为应该可以进行所有操作
First, all works as I think it should:
Overriden call to private method ----------------
1
2
2
然后,如果我调用了未实现的父方法,则继承的类的私有方法就会消失.可以将其解释为所有私有方法都是最终的,并且对派生类隐藏",因此 invokeNotOverriden()
对Test2类中的方法一无所知:
Then, inherited class's private method dissapears, if I called non-implemented parent method. It could be explained as "All private methods are final and hidden from derived classes", so invokeNotOverriden()
doesn't know anything about methods in Test2 class:
Call to private method from parent class ----------------
1
1
1
最后,在静态类中,当我调用非静态私有方法时,突然出现了一些魔术:
Finally, in static class some magic suddenly appears when I call non-static private method:
Some magic ----------------
1
2
1
我希望在这里 1 2 2
.我为什么错了?
I expected 1 2 2
here. Why am I wrong?
推荐答案
您已经在一些魔术
部分中获得了 1 2 1
,因为私有方法是使用w/o多态性,编译器会创建对包含在使用 Test3
声明的类型变量中的方法的调用.在 Test3
中将 print1
声明为非私有(因此,在 Test4
中声明,因为它被禁止加强方法的访问修饰符),并在动作,这样您就可以得到预期的 1 2 2
.
You've got 1 2 1
in some magic
section, because private methods are resolved w/o polymorphism, compiler creates call to method contained in type variable declared with, in your case Test3
. Declare print1
as non-private in Test3
(and, consequently, in Test4
as it's prohibited to tighten access modifiers of methods) and see polymorphism in action, so you'll get expected 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();
}
}
澄清 ... ...我对这个答案的评论:多态性对于访问数据字段无效,仅对方法有效.考虑:
CLARIFICATION ... to my comment to this answer: polymorphism isn't effective for access to data fields, only for methods. Consider:
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
.
Despite i
declared non-private, t34.i
value is 1
.
这篇关于覆盖(非)静态类中的私有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!