gpt4 book ai didi

java - 令人困惑的 Java 多态性

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:51:49 24 4
gpt4 key购买 nike

考虑这段代码(完整的类,运行良好,为简洁起见,所有类都在一个类中)。

我的问题在代码 list 之后:

import java.util.LinkedList;
import java.util.List;

class Gadget {
public void switchon() {
System.out.println("Gadget is Switching on!");
}
}

interface switchonable {
void switchon();
}

class Smartphone extends Gadget implements switchonable {
@Override
public void switchon() {
System.out.println("Smartphone is switching on!");
}
}

class DemoPersonnel {
public void demo(Gadget g) {
System.out.println("Demoing a gadget");
}

public void demo(Smartphone s) {
System.out.println("Demoing a smartphone");
}
}

public class DT {

/**
* @param args
*/
public static void main(String[] args) {
List<Gadget> l = new LinkedList<Gadget>();
l.add(new Gadget());
l.add(new Smartphone());
for (Gadget gadget : l) {
gadget.switchon();
}

DemoPersonnel p = new DemoPersonnel();
for (Gadget gadget : l) {
p.demo(gadget);
}
}
}

问题:

  1. 从编译器的角度来看,Smartphone 中 switchon 方法的起源是什么?是继承自基类Gadget吗?或者它是 switchonable 接口(interface)强制执行的 switchon 方法的实现?这里的注解有什么区别吗?

  2. 在 main 方法中,第一个循环:在这里,我们看到了运行时多态性的情况 - 即,当第一个 for 循环运行并调用 gadget.switchon() 时,它首先打印“Gadget is switching on”,然后打印“Smartphone is switching on”。但是在第二个循环中,这种运行时解析不会发生,并且两次调用 demo 的输出都是“Demoing a gadget”,而我期望它在第一次迭代中打印“Demoing a gadget”和“Demoing a smartphone”第二次。

我哪里理解错了?为什么运行时在第一个 for 循环中解析子类,但在第二个 for 循环中不解析?

最后,将感谢有关 Java 运行时/编译时多态性的清晰教程的链接。 (请不要发布 Java 教程跟踪链接,在相当深入地讨论更细微的差别时,我没有发现这些 Material 特别令人印象深刻)。

最佳答案

这就是它的工作原理:
编译时间

  • 编译器为请求的方法定义所需的签名
  • 一旦定义了签名,编译器就开始在type-Class中寻找它
  • 如果找到任何具有所需签名 yield 的兼容候选方法,否则返回错误

运行时

  • 在执行期间,JVM 开始寻找具有在编译时定义的完全 签名的候选方法。
  • 可执行方法的搜索实际上是从真正的对象实现类(可以是类型类的子类)开始,并向上遍历整个层次结构。

您的列表定义为小工具类型。

for (Gadget gadget : l) {
gadget.switchon();
}

当您请求 gadget.switchon(); 时,编译器将在 Gadget 类中寻找 switchon() 方法,因为它在那里,候选签名很简单确认为 switchon()

在执行期间,JVM 将Smartphone 类 中寻找switchon() 方法,这就是它显示正确消息的原因。

这是第二个 for 循环中发生的事情

DemoPersonnel p = new DemoPersonnel();
for (Gadget gadget : l) {
p.demo(gadget);
}

在这种情况下,签名是针对两个对象 demo(Gadget g),这就是为什么两次迭代都执行方法 demo(Gadget g) 的原因。

希望对您有所帮助!

关于java - 令人困惑的 Java 多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17634495/

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