gpt4 book ai didi

java - 对编译器处理继承和方法调用感到困惑

转载 作者:行者123 更新时间:2023-11-30 05:58:34 27 4
gpt4 key购买 nike

在阅读了一些有关继承和方法调用以及编译器如何处理这些的信息后,我感到很困惑。因此,如果有人能看看我如何看待事物并纠正我的错误,我将不胜感激。

我们首先看一下下面的代码:

A类:

public class A {

public void testMethodA(String a) {
System.out.println(a);
}

}

B类:

public class B extends A {


}

主要

public class Main {

public static void main(String[] args) {
B b = new B();
b.testMethodA("test");
}

}

现在让我们看看我的理解方式(如果我错了,请纠正我):

  1. 在继承过程中,创建子类对象时,您将创建一个接收所有父类(super class)的所有字段和方法的对象。因此子类的字段和方法在编译时不会从父类(super class)转移到子类(来源:Does an instance of superclass get created when we instantiate an object?)
  2. 在编译时,编译器会检查所调用的支持参数类型的方法是否在声明的引用类型中定义。所以在这个例子中:A a = new A(); a.testMethod("test")它会在编译时检查 testMethod() 是否在类 A 中定义,并且可以接收 String 作为参数。 (来源:How does java compiler choose correct methods and variables in inheritance)
  3. 当运行时发生时,从存储在变量a中的实际对象调用testMethod(),该对象并不总是A类型的对象 由于多态性。

现在实际问题:

根据我上面描述的逻辑和代码,我预计在编译时会出现无法解析方法错误。原因是在编译期间,编译器会检查类 B 是否存在 testMethodA(String) 。然而,该方法是从类 A 继承的,据我了解,继承的方法不会传递给子类,而是在运行时传递给子类的对象。那么如果编译时类B中不存在testMethodA(String),编译器如何能够成功编译代码呢?当然,它不会检查该方法的对象,因为该对象尚未创建。

这个问题在“可能的答案”中没有得到回答,因为这个线程是我自己在描述这个问题时标记为知识来源的线程。

最佳答案

我认为,您的主要误解在于第2点。

During compile time, the compiler checks if the called to method that supports the argument type is defined in the declared reference type.

这应该更好地阅读:

在编译时,编译器会检查所调用的支持参数类型的方法是否在声明的引用类型或其父类(super class)型之一或整个树中实现的接口(interface)中定义

编译器知道 B 的任何实例(作为 A 的子类)都会有一个方法 testMethodA(),可以是从父类(super class) A 继承,或者从子类重写,因此调用该方法是安全的。

您使用“pass”一词来描述从父类(super class)到子类的字段和方法的继承。这个措辞让我听起来很困惑,因为它意味着一些重复过程,而这些过程只发生了一部分。对于实例字段,这或多或少是可以的,因为子类的每个实例都将获得父类(super class)字段加上子类字段的单独副本。但是方法不会被复制到实例,它们保留在定义它们的类中(如果添加方法,实例不会占用更多内存)。在内部,Java 运行时维护某种查找表来查找给定实例的类的适当方法版本。

所以我认为,“将方法传递给子类对象”这种措辞并不符合实际流程。

关于java - 对编译器处理继承和方法调用感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52690412/

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