gpt4 book ai didi

java - Java 中的方法覆盖和重载

转载 作者:搜寻专家 更新时间:2023-10-31 08:15:14 24 4
gpt4 key购买 nike

当我遇到一些奇怪的事情时,我正在测试代码,我无法弄清楚为什么会这样。所以我将举一个简单的例子来说明那里发生了什么。

考虑这些类

public class A {
public void print(A a) {
System.out.println("A");
}
}

public class B extends A {
public void print() {
System.out.println("B");
}
}

public class C extends B {
public void print(A a) {
System.out.println("C");
}
}

public class E extends C {
public void print(E e) {
System.out.println("E");
}
}

现在在我的主要方法中我有这种实例化:

    B b = new E();
C c = new E();
E e = new E();

我调用这些方法并获得以下输出。

    b.print(b);
c.print(e);

输出:

C
C

我有两种解释,但每一种都与其中一种方法调用相矛盾。也有可能我的两种解释都是完全错误的,所以我不在这里声明任何内容。

解释一

  • b.print(b):bE 的一个实例,并向上转换为 BB 有一个print 方法,该方法采用A 类型的参数,但它被类E 重载了。然而,此方法的参数是 b,它被向​​上转换为 B,因此该方法调用与 C.print(A a) 的签名相匹配>(因为 CE 的父类(super class))因此结果是有理数。

  • c.print(e): 和上面的思路一样,输出结果这里就不多说了。 cE 的一个实例,并被向上转换为 CC 有一个print 方法,该方法采用A 类型的参数,但它被类E 重载了。但与上述情况相反,此方法的参数是 e,它与 E.print(E e) 的签名相匹配。所以根据这个推理,输出应该是 E 而不是!

解释2

这里我从第二个方法调用开始,并说明原因。

  • c.print(e):cE 的一个实例,并向上转换为 CC 有一个 print 方法,该方法采用 A 类型的参数。此方法的参数是 e,它是 E 的实例,而 E 又是 A 的子类。由于它已被向上转型,E.print(E e)c 是隐藏的。因此,该方法调用与C.print(A a) 的签名相匹配,并且按此逻辑输出是合理的。

  • b.print(b):bE 的一个实例,并向上转换为 BB 有一个 print 方法,该方法采用 A 类型的参数(同样它是隐藏的)。因此,该方法调用与 A.print(A a) 的签名相匹配,根据这个逻辑,输出应该是 A 而不是。

我真的很困惑这里发生了什么。有人可以解释一下吗。

最佳答案

调用哪个方法分两步决定:

  • 在编译时,根据声明的实例类型决定使用哪些重载方法
  • 在运行时,根据实际实例类型(多态性)决定使用哪些覆盖方法

    1. b.print(b);//B b = new E();

      • 在编译时,由于b的声明类型是Bprint接受B<的实例(或其父类(super class)(A))只能被使用,这意味着:A.print(A a)

      • 在运行时,一旦在上一步中选择了重载方法,就会使用 b (E) 的实际类型来选择版本print(A a) 将被使用:C.print(A a) over A.print(A a)

    2. c.print(e);//C c = new E(); E e = new E();

      • 编译时,c的声明类型为Ce的声明类型为E 所以只能使用这些方法:A.print(A a)C.print(A a)

      • 在运行时,e 的实际类型是 E 因此选择更具体(意味着在类层次结构中更高)的版本:C .print(A a)

关于java - Java 中的方法覆盖和重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16744507/

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