1

当您有一个实现了方法行为的抽象类以及没有实现任何行为时,方法调用的顺序是什么?

假设我的抽象类称为 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 然后再到子类吗?是不是先去子类,因为sublclass是作为参数传入的,然后JVM会检查子类中是否提供了实现代码,如果没有,如果有实现代码就调用超类方法?

4

2 回答 2

3

如果子类重写了一个方法,那么根本不调用父方法实现,除非子类有super.overridenMethodName()调用。它可以在被覆盖方法实现的开头或结尾或任何其他位置。

另一方面,如果一个抽象类有一个抽象方法,那么子类在编译时被强制实现它并提供一些逻辑。

于 2011-08-20T14:12:48.780 回答
0

对于非静态方法m,方法调用表达式o.m()是通过确定所引用对象的运行时类来执行的o。然后,调用该类的方法实现(在类本身中继承或定义)。

每个类都从其超类继承每个(可见)方法,除非它声明具有相同签名的方法,在这种情况下,声明的方法实现会覆盖继承的方法。

换句话说,调用的最具体的超类中的实现。就这些; 特别是,不会自动调用该方法的继承实现。当然,被调用的方法可以反过来调用任何继承的方法实现,使用super.m().

请注意,方法调用的规则是不同的static。此外,虽然接收器的运行时类(o在我们的示例中)确定要调用的方法,但重载是使用参数的编译时类型解决的,而不是它们的运行时类型。

于 2011-08-20T15:45:01.187 回答