[英]How does inheritance in Java work?
We have next classes: 我们有下一堂课:
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();
}
}
Output is: 输出是:
Super
超
Sub
子
What does super
present? super
礼物是什么? Is it object of parent class, which child keeps as field? 它是父类的对象,哪个孩子保持为字段?
I tried to Google, but all I found is common information about how to inherit classes and so on. 我试过谷歌,但我找到的只是关于如何继承类等的常见信息。
You are still telling me obvious things. 你还在告诉我显而易见的事情。 Maybe my question was little misleading, but I'll try to rephrase it:
也许我的问题有点误导,但我会试着改写它:
super
, you say, we are accessing parent's method. super
调用方法时,你说,我们正在访问父方法。 But how can we call this method without parent's object? super
same as this
? super
同this
? this
is a reference to concrete object, as you know. this
是对具体对象的引用。 The child class does not maintain any special field representing its parent. 子类不维护任何表示其父级的特殊字段。 You may be thinking something along the lines of inner classes, which do maintain a reference to their outer class.
你可能正在思考内部类的某些东西,它们确实维护了对它们外部类的引用。 This is a special case and does not represent how super-sub classes relate to each other.
这是一种特殊情况,并不代表超级子类彼此之间的关系。
Internally, the JVM maintains a 'method table', associating each class its loaded with the methods available for that class. 在内部,JVM维护一个'方法表',将其加载的每个类与该类可用的方法相关联。 The JVM also knows about the relationships between all classes its loaded, including super-sub relationships.
JVM还知道它加载的所有类之间的关系,包括超子关系。
When you invoke a super
function, the JVM actually does a couple of things: 当您调用
super
函数时,JVM实际上做了以下几件事:
invokespecial
) invokespecial
) If you were to examine the class file for your Sub
class, you would see something like this for the foo
method: 如果您要检查
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
Line 1 in the listing shows the special instruction that invokes the superclass method. 清单中的第1行显示了调用超类方法的特殊指令。
A good source of reading would be the Java Virtual Machine Specification , particularly Section 2.11.8 . 读取的一个很好的来源是Java虚拟机规范 ,特别是第2.11.8节 。
Okay. 好的。 Let's go, line by line through your code.
我们一行一步地通过您的代码。
Your first statement, in your 'foo' method is 你的'foo'方法中的第一个陈述是
super.foo();
Well that's an explicit call to the superclass foo
method. 那是对超类
foo
方法的显式调用。 Which is: 这是:
void foo() {
System.out.println("Super");
}
So "Super" is outputted to the console, becuase you've explicitly called this method with the super
keyword. 所以“Super”输出到控制台,因为你已经用
super
关键字明确地调用了这个方法。 super
refers to the class' superclass, in the same way that this
refers to the current class. super
指的是类的父类,以同样的方式, this
指的是当前类。
Next is the rest of the foo
method in the subclass: 接下来是子类中
foo
方法的其余部分:
void foo() {
super.foo();
System.out.println("Sub");
}
Well after super.foo()
is called, it's time to move to the next statement, which outputs "Sub". 在
super.foo()
之后,是时候转到下一个语句,输出“Sub”。
The reason why your program moves to the subclass' method first, instead of the superclass, is because of a principle called Polymorphism
. 你的程序首先移动到子类'方法而不是超类的原因是因为一个叫做
Polymorphism
的原理。 That is, a subclass takes a method from the superclass, and alters it's behavior. 也就是说,子类从超类中获取一个方法,并改变它的行为。
Abstract Classes
抽象类
You can't create instances of Abstract classes, no, but with the super
keyword, you can access the functionality of the superclass nonetheless. 您不能创建Abstract类的实例,不能,但是使用
super
关键字,您仍然可以访问超类的功能。
In context of the Java Virtual Machine
在Java虚拟机的上下文中
So what happens, when you make a method call, is the Java Virtual Machine will look for the method in the local class, if it is an instance method. 那么,当您进行方法调用时,如果它是实例方法,Java虚拟机将在本地类中查找该方法。 If it can not find it, it will move to the superclass.
如果找不到它,它将移动到超类。 When you use the principle of
Polymorphism
, the JVM finds the method with the correct signature in the subclass, and stops looking. 当您使用
Polymorphism
原理时,JVM会在子类中找到具有正确签名的方法,并停止查找。 This is how inheritance and Polymorphism
works in simple terms, in the context of Java. 这就是继承和
Polymorphism
在Java的上下文中以简单的方式工作的方式。
When you override a method, you add a method with the same method signature (the name, number and type of a method's fields) to the subclass definition. 覆盖方法时,可以向子类定义添加具有相同方法签名(方法字段的名称,编号和类型)的方法。 This is how the JVM finds it, and this is where the overridden method is stored.
这就是JVM找到它的方式,这是存储重写方法的地方。
super
is a keyword allowing you to call the method implementation defined in the superclass. super
是一个关键字,允许您调用超类中定义的方法实现。 It is not a field of your sub-class. 它不是你的子类的一个领域。
If it is not, where are overrided method hold?
如果不是,那么覆盖的方法在哪里举行?
I'm not quite sure what you mean by this, but: 我不太清楚你的意思,但是:
Since Sub
extends Super
, the definition of the Sub
class includes a reference to the definition of the Super
class. 由于
Sub
扩展了Super
, Sub
类的定义包括对Super
类定义的引用。
Answering updated questions: 回答更新的问题:
When we are calling method with super, you say, we are acessing parent's method.
当我们用super调用方法时,你说,我们正在进行父方法。 But how can we call this method without parent's object?
但是如何在没有父对象的情况下调用此方法呢?
A method is just a block of code, just a sequence of bytecode instructions that we need to execute. 方法只是一个代码块,只是我们需要执行的一系列字节码指令。 When you invoke a method, the JVM's task is to determine, from the method name and parameters you give, where to find this block of code.
当您调用方法时,JVM的任务是根据您提供的方法名称和参数确定在哪里找到此代码块。 Normally, as others have said, it will first look in the class definition of the class of the object on which the method was invoked.
通常,正如其他人所说,它将首先查看调用该方法的对象的类的类定义。 When you use
super
, you are telling the JVM not to look here, and instead look in the parent class definition. 当你使用
super
,你告诉JVM不要看这里,而是查看父类定义。
So you don't need separate instances of Super
and Sub
, because a Sub
is a Super
( new Sub() instanceof Super
is true
), and because the JVM knows that the super
keyword means that it should look for the code composing a method in the class definition of Super
. 因此,您不需要单独的
Super
和Sub
实例,因为Sub
是 Super
( Super
new Sub() instanceof Super
是true
),并且因为JVM知道super
关键字意味着它应该查找构成方法的代码在Super
的类定义中。
Is super same as this?
这个超级一样吗? this is a reference to concrete object, as you know.
如您所知,这是对具体对象的引用。
No, they're not the same. 不,他们不一样。
this
is a reference to the current object, whereas super
is not a reference to an object, instead it is a keyword which affects where the JVM will look for the code defining a method which is being invoked. this
是对当前对象的引用,而super
不是对对象的引用,而是一个关键字,它影响JVM查找定义正在调用的方法的代码的位置。
when you write super.foo();
当你写
super.foo();
you are calling the superclass method. 你正在调用超类方法。
The foo method of class sub overrides the foo method of Super by adding an instruction to the super class method. class sub的foo方法通过向超类方法添加指令来覆盖Super的foo方法。
foo method override in sub class .super.foo() calling print super and then System.out.println("Sub"); 子类.super.foo()中的foo方法覆盖调用print super,然后调用System.out.println(“Sub”); shows Sub.
显示Sub。
try this for inheritence 试试这个继承
class Super {
Super()
{
System.out.println("1");
}
void foo() {
System.out.println("Super");
}
}
class Sub extends Super {
public Sub() {
// TODO Auto-generated constructor stub
System.out.println("2");
}
void foo() {
super.foo();
System.out.println("Sub");
}
}
There is only one object that is simultaneously a Sub, and a Super, and an Object. 只有一个对象同时是Sub,Super和Object。 It has all the non-static fields for each of those classes.
它具有每个类的所有非静态字段。 A class only really needs one copy of the code for its methods, even the non-static ones.
一个类实际上只需要一个代码副本用于其方法,甚至是非静态代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.