java覆盖方法调用
我有一个超级class:
public class SuperClass { public void dosomething() { firstMethod(); secondMethod(); } public void firstMethod() { System.out.println("Super first method"); } public void secondMethod() { System.out.println("Super second method"); } }
子类:
public class SubClass extends SuperClass { public void dosomething() { super.dosomething(); } public void firstMethod() { System.out.println("Sub first method"); } public void secondMethod() { System.out.println("Sub second method"); } }
测试类:
public static void main(String[] args) { SubClass sub = new SubClass(); sub.dosomething(); SuperClass sup = new SuperClass(); sup.dosomething() }
当我运行测试方法时,我得到了这个:
Sub first method Sub second method
你能告诉我这是怎么发生的吗? 在子类super.dosomething()
方法中,我调用了super.dosomething()
,我认为将调用super方法,但是调用了子类中的override方法。
如果我这样做:
SuperClass superClass = new SuperClass();
superClass.dosomething();
结果是:
超级第一种方法
超级第二种方法
区别在于方法调用的地方。 我认为必须有一些我不知道的东西):
哎呀!超级引用指向第一个例子中的子类…
像这样:
SuperClass sub = new SubClass();
sub.firstMethod();
sub.secondMethod();
调用方法的对象是SubClass类型,而不是SuperClass。 即使您调用仅在SuperClass中定义的方法,您的执行上下文仍然是SubClass。 因此,被覆盖的任何被调用的方法实际上都会执行重写的方法。
从中可以看出,通过将firstMethod和secondMethod声明为public,SuperClass实际上允许子类覆盖它们的行为。 如果这不合适,方法应该是私有的或最终的。
在java中,方法绑定始终是动态的 [忽略静态和私有方法]。 因此,当您重写firstMethod()
和secondMethod()
, secondMethod()
SubClass
类型的对象尝试调用其中一个对象 – 将调用overriden方法 – 即使它[invokation]来自父方法。
因此,正如预期的那样 – 当您调用super.doSomething()
,它会调用firstMethod()
和secondMethod()
,并且正在调用overriden方法。
事实上,超级doSomething被称为。 做一些事情调用firstMethod和secondMethod,它们是虚方法(Java中的任何方法默认都是虚拟的,这意味着它可以被覆盖)。 因此他们的覆盖版本被调用。
如果将它们标记为最终,则可以防止它们被覆盖。
Super.dosomething()
确实在Super
类中调用了Super.dosomething()
方法。 但是在这个方法中,你调用了2个函数,即firstMethod
和secondMethod
。 这些方法在Sub
类中被覆盖,并且它们是从Sub
Class调用的。
正如Petar Ivanov所说:
如果将它们标记为最终,则可以防止它们被覆盖