英文:
Why the parent class will call the subclass method in java?
问题
我有两个类:
public class A {
void add(int a){
System.out.println("A.add");
}
void addAll(int[] a){
System.out.println("A.addAll");
for(int i = 0;i < a.length;i++){
add(a[i]);
}
}
}
public class B extends A{
@Override
void add(int a){
System.out.println("B.add");
super.add(a);
}
@Override
void addAll(int[] a){
System.out.println("B.add");
super.addAll(a);
}
public static void main(String[] args){
(new B()).addAll(new int[]{1,2,3,4});
}
}
当我开始运行这个应用程序时,输出是:
B.add
A.addAll
B.add
A.add
B.add
A.add
B.add
A.add
B.add
A.add
为什么类A中的addAll
函数会调用类B中的add
函数,而不是调用自己的add
函数?
英文:
I have two classes:
public class A {
void add(int a){
System.out.println("A.add");
}
void addAll(int[] a){
System.out.println("A.addAll");
for(int i = 0;i < a.length;i++){
add(a[i]);
}
}
}
public class B extends A{
@Override
void add(int a){
System.out.println("B.add");
super.add(a);
}
@Override
void addAll(int[] a){
System.out.println("B.add");
super.addAll(a);
}
public static void main(String[] args){
(new B()).addAll(new int[]{1,2,3,4});
}
}
And when I start to run this application, the output is
B.add
A.addAll
B.add
A.add
B.add
A.add
B.add
A.add
B.add
A.add
Why the addAll
function in class A will call the add
function in class B rather than call its own add
function?
答案1
得分: 2
我认为Derek误解了你的意思。Super
确实指的是父类(A),但你可以看到在B的add
函数之前有一个@override
关键字。由于是B对象调用了addAll
函数(new B()
),A的add
被B的add
函数覆盖了。因此,它首先调用B的add
函数,然后是A的add
函数。
英文:
I think Derek has misunderstood your meant. Super
indeed refers to the parent class (A), but you can see there's a @override
keyword before B's add
function. Since it is a B object calls addAll
function (new B()
), the A's add
is override by B's add
function. Therefore it calls B's add
function first, then A's add
function.
答案2
得分: 2
因为这就是多态的工作原理。任何非私有的/静态的/终态的方法都可以被重写,无论你是从类外部还是内部调用它。
在类 A 中,在 addAll()
中调用了一个非私有方法 add()
。如果你在子类 B 中重写了 add()
方法,A 中的 addAll()
将会调用 B 的 add()
方法。这是非常明显的。
实际上,我认为让你困惑的是为什么会这样工作。
在 Java 中,如果你将一个方法声明为非私有和非终态的,那么你是在告诉任何子类可以改变它的行为,这就是重写的意思。如果你不希望子类改变它的行为,你可以将它声明为私有的或者终态的,或者将你的类声明为终态的。
英文:
Because that's how polymorphism works. Any non-private/static/final method can be overrided, no matter you call it from outside of the class or inside.
In class A,you call a non-private method add()
in addAll()
. If you override add()
method in subClass B, the addAll()
in A will call the B's add()
method.This is quite obvious.
In fact I think what confuse you is why it work like that.
In java, if you declare a method as non-private and non-final, you are telling that any subclass can change it's behavior, that's what override means. If you don't want subclass to change it's behavior, you can either declare it as private or final or make you class final.
答案3
得分: 0
这就是动态方法调度。调用的引用是“B”,它已经覆盖了“A”的add()和addAll()方法。现在,当B的引用调用addAll()时,将调用B的版本。这里没有什么不明显的。现在,B的addAll的版本有super.addAll(),这也是直观的。有趣的是,当调用A的addAll()的主体时,它调用了“add()”。在这里,由于启动整个调用链的运行时引用是B,而且B也已经覆盖了A的“add()”,因此在A的“addAll()”主体内部调用了B的“add()”版本。动态方法调度和运行时多态性决定了这种行为,其中在调用中分派的所有方法都取决于调用变量具有的实际引用。
英文:
This is dynamic method dispatch. The calling reference is of "B" which has overridden both add() and addAll() of "A". Now, when B's reference invokes addAll(), B's version is called. Nothing not obvious here. Now B's version of addAll has super.addAll(), which also think is intuitive.
What's interesting is that when the body of A's addAll() is invoked, it has invocation to "add()". Here, since the runtime reference using which the entire call chain was started is of B and B has overridden "add()" of A as well, thus B's version of "add()" is invoked from within the "addAll()" body of A.
Dynamic method dispatch and runtime polymorphism dictates this behaviour where all methods that are dispatched in an invocation depends on the actual reference that the invoking variable has.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论