Java中的继承如何工作?

lie*_*ies 8 java inheritance

我们有下一堂课:

class Super {
    void foo() {
        System.out.println("Super");
    }
}

class Sub extends Super {
    void foo() {
        super.foo();
        System.out.println("Sub");
    }
}

public class Clazz {
    public static void main(String[] args) {
        new Sub().foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

问题:

什么super礼物?它是父类的对象,哪个孩子保持为字段?

  • 如果是,抽象类的继承如何工作?您无法创建抽象类的实例.
  • 如果不是,那么被覆盖的方法在哪里举行?

我试过谷歌,但我找到的只是关于如何继承类等的常见信息.

更新:

你还在告诉我显而易见的事情.也许我的问题有点误导,但我会试着改写它:

  • 当我们调用方法时super,你说,我们正在访问父方法.但是如何在没有父对象的情况下调用此方法呢?
  • super一样的thisthis如你所知,是对具体对象的引用.

Per*_*ion 6

子类不维护任何表示其父级的特殊字段.您可能正在思考内部类的某些内容,这些内部类确实维护对其外部类的引用.这是一种特殊情况,并不代表超级子类彼此之间的关系.

在内部,JVM维护一个'方法表',将其加载的每个类与该类可用的方法相关联.JVM还知道它加载的所有类之间的关系,包括超子关系.

当您调用super函数时,JVM实际上做了以下几件事:

  • 确定要从中调用方法的类的父级
  • 确定将要调用的父级的方法
  • 使用特殊指令调用该方法(invokespecial)

如果你要检查你的Sub类的类文件,你会看到这样的foo方法:

void foo();
    flags: 
    Code:
        stack=2, locals=1, args_size=1
            0: aload_0       
            1: invokespecial #2        // Method Super.foo:()V
            4: getstatic     #3        // Field java/lang/System.out:Ljava/io/PrintStream;
            7: ldc           #4        // String Sub
            9: invokevirtual #5        // Method java/io/PrintStream.println:(Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)

清单中的第1行显示了调用超类方法的特殊指令.

读取的一个很好的来源是Java虚拟机规范,特别是第2.11.8节.