对继承 Java 中的方法和字段感到困惑

我试图对子类如何访问超类的方法和字段进行一些研究。当我在 stackoverflow 上阅读解释继承“真正”如何工作的帖子时,我对看到我的输出感到困惑。

看完这篇文章后,这是我对继承的理解,如果有错误,请您纠正:


方法和字段不会复制到子类,而是从超类对象调用,除非在子类中被覆盖。我已经使用javap命令确认方法和字段没有被复制到子类。

当调用子类中的方法时,它会在运行时查找子类对象中的方法(一种可能的覆盖方法),如果没有找到,它将在层次结构中上升到超类对象中,然后从超类对象。

因为方法和字段不是复制到子类而是从超类对象调用,所以子类构造函数调用 super(); 隐式地确保有一个 Superclass 对象可用于调用继承的方法。

应用我刚刚写下的逻辑,我遇到了一些奇怪的输出。在下面的示例中,我有 A 类(Superclass)和 B类(Subclass)。我从 Main 方法接收 B 作为输出,但期望 A 作为输出。


A类:


public class A {

    public void getTheClass() {

        System.out.println(getClass().getSimpleName());

    }

}

B类:


public class B extends A {

    public B() {

        getTheClass();

    }


}

班级主要:


public class Main {

    public static void main(String[] args) {

        B b = new B();

    }

}

我期望 A 作为输出的原因是因为(根据前面描述的逻辑)getTheClass()方法将从超类对象 (A) 中调用,因为子类对象 (B) 没有名为 getTheClass() 的方法. Subclass 对象没有这个方法是因为根据我的理解,方法和字段并没有复制到子类中。


如果子类没有这个方法,它将在层次结构中向上搜索一个对象,并从那里调用它,在这种情况下就是超类对象 (A)。因此,如果从超类对象(A)调用getTheClass()方法,那么对象的类不就是类 A 而不是类 B 吗?在那种情况下,为什么它不输出 A 而是输出 B?如果我打印出关键字this ,我会得到同样令人困惑的结果。


沧海一幻觉
浏览 183回答 1
1回答

慕森卡

因为当在子类对象中找不到被调用的方法时,它会在层次结构中上升,所以子类构造函数调用 super(); 隐式地确保有一个 Superclass 对象可用于调用继承的方法。构造函数(在子级和父级中)将在您创建对象本身时调用,而不是在您调用对象上的方法时调用(因为您需要一个完全构造的对象来调用其上的方法)。您看不到打印的类名的原因A是该getClass()方法返回对象的运行时类型(即B)来自javadoc,(强调我的)返回此 Object的运行时类。返回的 Class 对象是被表示的类的静态同步方法锁定的对象。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java