Java多态性序列


public class A {
int method(A a) { return 1; }
static int method(B b) { return 2 + b.method((A)b); }
}
public class B extends A {
final int method(A a) { return 4 + super.method(a); }
int method(C c) { return 8 + this.method((B)c); }
}
public class C extends B {
int method(C c) { return 16 + method((A)c); }
} 
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
b.method(b);  //returns 7 (4 + 2 + 1)
b.method(c);  //returns 15 (8 + 4 + 2 + 1)
}
}

每个类都在自己的文件中。

为什么第一个呼叫返回7?对我来说,它应该返回其他东西,因为调用了B.方法(A(,然后调用了A.(B(,然后应该调用B中的东西,而不是A.(A(为什么第二个呼叫返回15?

有两种有效的方法可以为b.method(b);:调用

final int method(A a) { return 4 + super.method(a); }
static int method(B b) { return 2 + b.method((A)b); } // inherited from A

编译器选择了一个更具体的method(B)。它是静态的并不重要。静态方法也可以在实例上调用。另请参阅:是通过对象调用静态方法吗;糟糕的形式"?为什么?

现在我们需要解决b.method((A)b);b的编译时类型是A,所以编译器只在A中搜索。参数表达式的编译类型也是A。唯一适用的方法是:

int method(A a) { return 1; }

在运行时,发现bB的实例,因此调用B中的重写方法:

final int method(A a) { return 4 + super.method(a); }

现在我们解决super.method(a);。这里涉及的类型与b.method((A)b);中的类型完全相同,但我们使用的是super,因此在B的超类中,即在A中的实现被调用:

int method(A a) { return 1; }

对于b.method(c);,参数的编译时类型是C,因此我们有三种适用的方法:

final int method(A a) { return 4 + super.method(a); }
static int method(B b) { return 2 + b.method((A)b); } // inherited from A
int method(C c) { return 8 + this.method((B)c); }

再次,选择最具体的method(C)

然后我们求解CCD_ 19。这是以与b.method(b);完全相同的方式解决的。编译时类型是相同的。参数的运行时类型是C对象这一事实并不重要,因为所有C重写都是method(C)方法,我们在解析b.method(b);时从未调用过该方法。

对于B,有效函数如下

final int method(A a) { return 4 + super.method(a); }
static int method(B b) { return 2 + b.method((A)b); }
int method(C c) { return 8 + this.method((B)c); }
  • 来自类B的重写方法(A A(
  • 同样在重载静态int方法(Bb(的原因中

请注意,静态方法也可以在实例上调用。

现在,当由于方法重载了多个参数而调用method时,它会查找参数适用于哪个方法。

b.method(b); //returns 7 (4 + 2 + 1)的函数调用堆栈

  1. 从类B调用方法(B B(返回2+B方法((A(B(
  2. 在类B方法(A A(中调用返回4+super.method(A(//由于super,它不调用重写的方法(A A(,它调用原始方法
  3. 在类A中调用静态int方法(A A(返回1

1 + 4 + 2 -> 7

对于b.method(c)

  1. 调用类B int方法(C C(返回8+this.method((B(C(
  2. 调用类B方法静态int方法(Bb(返回2+B.method((A(B(
  3. 调用类B最终int方法(A A(返回4+super.method(A(;//调用未覆盖的方法(A A(,因为super关键字
  4. 调用类A int方法(A A(返回1

1 + 4 + 2 + 8 -> 15

相关内容

  • 没有找到相关文章

最新更新