我们有下一节课:
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();
}
}
输出是:
Super
Sub
问题:
super
代表什么?它是父类的对象,哪个 child 保留为字段?
- 如果是,抽象类的继承是如何工作的?您不能创建抽象类的实例。
- 如果不是,覆盖的方法在哪里?
我尝试用 Google 搜索,但我找到的只是关于如何继承类等的常见信息。
更新:
你还在告诉我显而易见的事情。也许我的问题有点误导,但我会尝试重新措辞:
- 当我们用
super
调用方法时,您说,我们正在访问父类的方法。但是我们如何在没有父对象的情况下调用这个方法呢? super
和this
一样吗?如您所知,this
是对具体对象的引用。
最佳答案
子类不维护任何表示其父类的特殊字段。您可能会按照内部类的思路进行思考,内部类确实维护对其外部类的引用。这是一个特例,并不代表超子类之间的关系。
在内部,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
list 中的第 1 行显示了调用父类(super class)方法的特殊指令。
一个很好的阅读资源是 Java Virtual Machine Specification , 特别是 Section 2.11.8 .
关于java - Java 中的继承是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15367152/