为什么内部类可以重写private final方法?

我想知道是否有意义的宣布私有方法是最终的,我认为这是没有意义的。 但我想象中有一种独特的情况,写下代码来搞清楚:

public class Boom { private void touchMe() { System.out.println("super::I am not overridable!"); } private class Inner extends Boom { private void touchMe() { super.touchMe(); System.out.println("sub::You suck! I overrided you!"); } } public static void main(String... args) { Boom boom = new Boom(); Boom.Inner inner = boom.new Inner(); inner.touchMe(); } } 

它编译和工作。 “我应该touchMe()最后”我以为做到了:

 public class Boom { private final void touchMe() { System.out.println("super::I am not overridable!"); } private class Inner extends Boom { private void touchMe() { super.touchMe(); System.out.println("sub::You suck! I overrided you!"); } } public static void main(String... args) { Boom boom = new Boom(); Boom.Inner inner = boom.new Inner(); inner.touchMe(); } } 

它也起作用并告诉我

 chicout@chicout-linlap:~$ java Boom super::I am not overridable! sub::You suck! I overrided you! 

为什么?

私有方法不能被覆盖(私有方法不会被inheritance!)事实上,如果你声明一个私有方法是最终的,那么它也没有什么区别。

你声明的两个方法, Boom.touchMeBoom.Inner.touchMe是两个完全独立的方法 ,它们恰好共享相同的标识符。 super.touchMe引用与super.touchMe不同的方法,这是因为Boom.Inner.touchMe 影响了 Boom.touchMe (而不是因为它覆盖了它)。

这可以通过多种方式来certificate:

  • 当你发现自己,如果你改变方法是公开的,编译器会抱怨,因为你突然试图覆盖最后的方法。

  • 如果你保持私有方法,并添加@Override注解,编译器会抱怨。

  • 就像alpian指出的那样,如果将Boom.Inner对象Boom.Inner转换为Boom对象( ((Boom) inner).touchMe() ),则调用Boom.touchMe (如果确实被覆盖,则不会影响转换)。

相关问题:

  • 使私有方法最终?

我认为这里实际上有两个独立的方法很好地certificate了通过改变你的主要如下:

 public static void main(String... args) { Boom boom = new Boom(); Boom.Inner inner = boom.new Inner(); inner.touchMe(); System.out.println("And now cast it..."); ((Boom)(inner)).touchMe(); } 

这现在打印:

 super::I am not overridable! sub::You suck! I overrided you! And now cast it... super::I am not overridable! 

在超级touchMe中调用super的原因是因为你在你的超级类( Boom )中查找了一个名为touchMe的方法,这个方法确实存在并且对于Inner来说是可见的,因为它在同一个类中。

私有方法对于子类或其他任何类都是不可见的,所以它们可以具有相同的名称,但不会相互超越。

尝试添加@Override注释 – 你会得到一个编译器错误。

您可以重写该方法,因为它对每个类都是private

你刚刚宣布了另一个同名的方法。 你可以调用类的私有成员,因为内部类本身就是类的成员。 希望这个修改会详细解释它。

 public class Boom { private final void touchMe() { System.out.println("super [touchMe] ::I am not overridable!"); } public void overrideMe(){ System.out.println("super [overrideMe]::I am overridable!"); } private class Inner extends Boom { private void touchMe() { super.touchMe(); System.out.println("sub [touchMe]::You suck! I overrided you!"); } public void overrideMe(){ System.out.println("sub [overrideMe] ::I overrided you!"); } } public static void main(String... args) { Boom boom = new Boom(); Boom.Inner inner = boom.new Inner(); inner.touchMe(); Boom newBoom = inner; newBoom.touchMe(); newBoom.overrideMe(); } } super [touchMe] ::I am not overridable! sub [touchMe]::You suck! I overrided you! super [touchMe] ::I am not overridable! sub [overrideMe] ::I overrided you!