gpt4 book ai didi

java - 在多态性问题上需要帮助

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:16:20 26 4
gpt4 key购买 nike

我有一个简单的代码,我想知道为什么以及如何选择某些方法而不是其他方法:

A 类:

public class A {
int f(A aa){
return 1;
}
}

B 类:

public class B extends A {
int f(A aa){
return 2;
}

int f(B bb){
return 3;
}
}

测试:

public class Test {
public static void main(String[] args) {
A a = new A();
A ab = new B();
B b = new B();

System.out.println(a.f(a));
System.out.println(a.f(ab));
System.out.println(a.f(b));

System.out.println(ab.f(a));
System.out.println(ab.f(ab));
System.out.println(ab.f(b));

System.out.println(b.f(a));
System.out.println(b.f(ab));
System.out.println(b.f(b));
}
}

现在,这个程序的输出如下:

1
1
1
2
2
2
2
2
3

现在,你能告诉我为什么 System.out.println(ab.f(b)) 输出 2 吗?

最佳答案

重载决议在编译时完成。 覆盖在运行时使用。

这意味着在编译时,编译器决定所有方法签名中的哪一个适合于方法调用。然后,在运行时,如果具有该签名的方法在正在使用的运行时对象中被覆盖,则使用被覆盖的方法。

在编译时,只有变量的静态类型 是已知的。也就是说,只考虑与变量的声明类型关联的方法签名。

在这种情况下,变量ab 被声明为A。因此,只有 A 中存在的方法签名才会被考虑用于调用 ab.f(b)A 类型中唯一的 ff(A aa) 方法。该方法签名的调用是合法的,因此编译器生成的代码说“此时,调用方法f,它有一个A类型的参数,并且将 b 作为参数传递给它。”

当运行时,由于 ab 实际上是一个 B 实例,方法 f 有一个 A 类型的参数 实际上在其中被覆盖了,所以它会打印 2,而不是 1

将此与 b.f(b) 进行对比。这里变量b的声明类型是B。因此,它有两个重载方法 f - 一个带有 B 参数,一个带有 A 参数。在编译 时,它已经知道参数b 被声明为B。所以最具体的重载是f(B bb)。该调用被翻译成“使用 B 类型的单个参数调用 f”。在运行时,这会打印 3。

区别是什么?在编译时,abA 类型,f(B bb) 不存在于该类型中。 bB 类型,f(B bb) 存在并且是最具体的重载。

关于java - 在多态性问题上需要帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34832316/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com