覆盖(非)静态类中的私有方法
Posted
技术标签:
【中文标题】覆盖(非)静态类中的私有方法【英文标题】:Overriding private methods in (non-)static classes 【发布时间】:2014-12-18 20:43:00 【问题描述】:我有这个测试代码示例:
公共类测试 私有静态类 Test3 私人无效打印1() System.out.println("1"); 私有静态类 Test4 扩展 Test3 私人无效打印1() System.out.println("2"); 公共静态无效主要(字符串[]参数) System.out.println("重写调用私有方法----"); 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("从父类调用私有方法----"); test1.invokeNotOverriden(); test2.invokeNotOverriden(); test12.invokeNotOverriden(); System.out.println("一些魔法----"); Test3 test3 = new Test3(); Test4 test4 = new Test4(); Test3 test34 = new Test4(); test3.print1(); test4.print1(); test34.print1(); 类外测试 公共静态类 Test1 公共无效调用覆盖() 打印1(); 公共无效调用NotOverriden() 打印1(); 私人无效打印1() System.out.println("1"); 公共静态类 Test2 扩展 Test1 @覆盖 公共无效调用覆盖() 打印1(); 私人无效打印1() System.out.println("2");首先,我认为一切正常:
重写对私有方法的调用---------------- 1 2 2然后,如果我调用未实现的父方法,继承类的私有方法就会消失。可以解释为“所有私有方法都是最终的并且对派生类隐藏”,所以invokeNotOverriden()
对 Test2 类中的方法一无所知:
最后,在静态类中,当我调用非静态私有方法时,突然出现了一些魔法:
一些魔法---------------- 1 2 1我期待1 2 2
在这里。为什么我错了?
【问题讨论】:
你不能重写私有方法——简单地说,就是这样。 我知道。而且我不会覆盖私有方法。我将类对象创建为Base b = new Inherited()
,并调用了它的私有方法。我认为,b
现在是Inherited
。为什么不是真的?
【参考方案1】:
您在some magic
部分中有1 2 1
,因为私有方法在没有多态性的情况下被解析,编译器创建对包含在用Test3
声明的类型变量中的方法的调用。在Test3
中将print1
声明为非私有(因此,在Test4
中,因为禁止收紧方法的访问修饰符)并查看多态性的作用,因此您会得到预期的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
。
【讨论】:
test34.getClass()
将 Test$Test4
显示为其类,而不是 Test3
。
这是一个类的动态解析(多态),它仅用于访问non-private
成员(数据和方法)。对于private
数据/方法,访问是使用程序中使用的类型完成的。
所以static
不是魔法的根源,如果我理解正确的话。只有private
方法修饰符。谢谢。【参考方案2】:
私有方法只对声明它们的类可用,而不是该类的子类。
如果您想在子类中使用父类中的方法,则必须将其设为 protected
。
在您的最后一个案例中,您强制转换为 Test3,因此出于所有意图和目的,该类认为它是 Test3 并调用 Test3 的 print 方法。静态实例不强制转换(您总是用它们的限定名来调用它们),所以它们总是调用它们自己的私有方法。
【讨论】:
关于最后一种情况。但第一次,没有静态,test12
调用 Test2
私有方法,而不是 Test1
【参考方案3】:
就像你说的,你不能覆盖private
方法,改成protected
【讨论】:
以上是关于覆盖(非)静态类中的私有方法的主要内容,如果未能解决你的问题,请参考以下文章