为什么内部类可以重写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.touchMe
和Boom.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!