【发布时间】:2012-05-29 14:06:19
【问题描述】:
在这个 C++ 程序中,
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"\n\nBase ctr";
fun();
}
virtual void fun()
{
cout<<"\n\nBase's fun()";
}
};
class Derived : public Base
{
public:
Derived()
{
cout<<"\n\nDerived ctr";
fun();
}
virtual void fun()
{
cout<<"\n\nDerived's fun()";
}
};
int main()
{
Derived obj;
return 0;
}
当使用 Derived 类对象从 Base 类的构造函数调用虚函数时,会调用 Base 的类 fun(),
输出::
基础点击率
Base 的 fun()
派生的ctr
Derived 的 fun()
原因解释here 但是
在这个java程序中,
class Base
{
Base()
{
System.out.println( "\n\nBase ctr" );
fun();
}
void fun()
{
System.out.println( "\n\nBase's fun()" );
}
}
class Derived extends Base
{
int a=1;
Derived()
{
System.out.println( "\n\nDerived ctr a = "+a );
a=8;
fun();
}
void fun()
{
System.out.println( "\n\nDerived's fun() a = "+a );
}
public static void main(String args[])
{
Derived obj = new Derived();
}
}
输出是 ::
基础点击率
Derived 的 fun() a = 0
导出 ctr a = 1
Derived 的 fun() a = 8
这里调用了派生类fun(),所以constraint应用于c++程序,不适用于JAVA程序。为什么?
【问题讨论】:
-
因为...它们是不同的语言,并且适用的规则不一样?
-
这条规则使得推理程序行为变得更加复杂,因为它是特殊情况下的方法调用规则。 Java 是关于简单规则的。
-
@MarkoTopolnik 仔细想想,C++ 方式更有意义。我记得读过 Java 程序员应该避免在构造函数中调用虚方法正是出于这个原因。
-
@Pubby 是的,这更有意义,是的,由于缺少此规则,Java 开发人员倾向于编写错误的习语。然而,由于设计选择保持简单,Java 中没有这条规则和许多其他类似规则仍然是事实。
-
@DavidRodríguez-dribeas 在 java 中,虚拟方法调用的行为始终类似于虚拟方法调用,在 c++ 中,此行为会在对象构造和剩余生命周期之间发生变化(调用的方法取决于 ctor 所处的状态) .我将一致的行为称为一个特性——我从来没有把关于虚拟方法调用的推理问题称为 java 特性,它是任何具有虚拟方法调用的语言的“特性”。 java 优势:Derived 类的开发人员可能希望更改 Base 的部分初始化方式(与任何其他方法一样,有其他方法可以做到这一点)