如果您有一个实现了方法行为的抽象类,并且没有实现任何行为,那么方法调用的顺序是什么?
让我们说我的抽象类叫做Abs,它有两个子类,Sub1和Sub2
在案例1中,Abs包含方法Meth1的实现代码
public abstract class Abs{
public void Meth1(){
//Some code
}
}
在一个完全不同的类中我有方法:
MyMethod(Abs a){
a.Meth1();
}
我传递Sub1或Sub2代替Abs
在案例2中,Abs不包含实现代码(但Sub1和Sub2执行)
public abstract class Abs{
public abstract void Meth1();
}
我打电话给同样的人:
MyMethod(Abs a){
a.Meth1();
}
传入Sub1或Sub2后。
每种情况下方法调用的顺序是什么?它总是去超类Abs然后到子类吗?它是否首先进入子类,因为子类作为参数传入,然后JVM检查子类中是否有实现代码,如果没有,那么如果有实现代码则调用超类方法?
答案 0 :(得分:3)
如果子类重写方法,则根本不调用父方法实现,除非子类具有super.overridenMethodName()
调用。它可以位于重写方法实现的开头或结尾或其他任何位置。
另一方面,如果抽象类有抽象方法,那么在编译时强制子类来实现它并提供一些逻辑。
答案 1 :(得分:0)
对于非静态方法m
,方法调用表达式o.m()
通过确定o
引用的对象的运行时类来执行。然后,调用该类的方法实现(在类本身内继承或定义)。
每个类都从其超类继承每个(可见)方法,除非它声明具有相同签名的方法,在这种情况下,声明的方法实现会覆盖继承的方法。
换句话说,在最具体的超类中实现调用。就这些;特别是,不会自动调用该方法的继承实现。当然,调用的方法可以使用super.m()
来调用任何继承的方法实现。
请注意,调用static
方法的规则不同。此外,虽然接收器的运行时类(在我们的示例中为o
)确定了要调用的方法,但是使用参数的编译时类型而不是运行时类型来解析重载。