我想知道为什么这条JAVA代码产生的输出与C ++中的相同代码不同。
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
A(){
this->Foo();
}
virtual void Foo()
{
cout << "A::Foo()" << endl;
}
};
class B : public A
{
public:
B()
{
this->Foo();
}
virtual void Foo()
{
cout << "B::Foo()" << endl;
}
};
int main(int, char**)
{
B objB;
system("pause");
return 0;
}
这会产生输出:
A::Foo()
B::Foo()
JAVA代码是:
public class Testa {
public Testa()
{
this.Foo();
}
public static void main(String[] args)
{
Testb b = new Testb();
}
void Foo()
{
System.out.println("A");
}
}
class Testb extends Testa {
public Testb()
{
this.Foo();
}
@Override
void Foo()
{
System.out.println("B");
}
}
此代码仅生成
B
B
为什么在这种情况下输出会有所不同?
答案 0 :(得分:5)
不同之处在于在构造过程中处理多态性。在Java中,对象的动态类型是派生类的动态类型,允许您甚至在构造函数有机会设置成员变量之前调用成员函数。这很糟糕。
C ++有一种不同的方法:在构造函数运行时,对象的类型被认为是构造函数所属的类之一。根据该假设,对成员函数的所有调用都是静态解析的。因此,A
的构造函数调用A::foo()
,而B
的构造函数调用B::foo()
。
答案 1 :(得分:2)
修改强>
我的回答的第一部分是在包含Java Testa
构造函数之前给出的。
在Java代码中,您没有像C ++代码中那样定义Testa
构造函数。这就解释了为什么只有一个B
用Java打印。
但即使你这样做,也要使代码更具等效性:
public Testa()
{
this.Foo();
}
会打印
B
B
因为在Java多态中,即使从构造函数中调用该方法也是如此。但这样做并不是一个好主意,因为在Testb
中调用方法Foo
时,对象Testb
的子部分仍然未初始化。