java多态序列

2exbekwf  于 2021-06-27  发布在  Java
关注(0)|答案(2)|浏览(311)
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.method(a),然后调用了a.(b),然后调用了b中的某个东西,而不是a.(a),为什么第二个调用返回了15?

rm5edbpk

rm5edbpk1#

对于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)
也是由于重载静态int方法(b)的原因
注意这里静态方法也可以在示例上调用。
现在什么时候 method 将被调用,因为方法已为多个参数重载它将查找参数适用的方法。
此函数的函数调用堆栈 b.method(b); //returns 7 (4 + 2 + 1)
来自类b方法(b)的调用返回2+b.method((a)b)
在类b中调用方法(a)返回4+super.method(a)//因为super,它调用的不是重写的方法(a)它调用的是原始方法
在类a中调用静态int方法(a)返回1 1 + 4 + 2 -> 7 为了 b.method(c) 调用类b int method(c c)返回8+this.method((b)c);
调用类b方法static int method(b b)返回2+b.method((a)b);
调用类b final int method(a)返回4+super.method(a);//调用not overwriten方法(a),因为super关键字
调用类a int方法(a)返回1 1 + 4 + 2 + 8 -> 15

vaj7vani

vaj7vani2#

可以调用两个有效的方法 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; }

在运行时, b 发现是的示例 B ,因此 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) 被选中。
然后我们决定 this.method((B)c); . 这个问题的解决方法与 b.method(b); . 编译时类型是相同的。参数的运行时类型是 C 对象并不重要,因为 C 覆盖是 method(C) 方法,解析时从未调用过 b.method(b); .

相关问题