Calling an overridden method from a parent class ctor(从父类ctor调用重写的方法)
问题描述
我尝试从父类的构造函数中调用被覆盖的方法,并注意到跨语言的不同行为.
I tried calling an overridden method from a constructor of a parent class and noticed different behavior across languages.
C++
- 回响 A.foo()
C++
- echoes A.foo()
class A{
public:
A(){foo();}
virtual void foo(){cout<<"A.foo()";}
};
class B : public A{
public:
B(){}
void foo(){cout<<"B.foo()";}
};
int main(){
B *b = new B();
}
Java
- 回响 B.foo()
Java
- echoes B.foo()
class A{
public A(){foo();}
public void foo(){System.out.println("A.foo()");}
}
class B extends A{
public void foo(){System.out.println("B.foo()");}
}
class Demo{
public static void main(String args[]){
B b = new B();
}
}
C#
- 回响 B.foo()
C#
- echoes B.foo()
class A{
public A(){foo();}
public virtual void foo(){Console.WriteLine("A.foo()");}
}
class B : A{
public override void foo(){Console.WriteLine("B.foo()");}
}
class MainClass
{
public static void Main (string[] args)
{
B b = new B();
}
}
我意识到在 C++ 中,对象是从层次结构的最顶层父级创建的,所以当构造函数调用被覆盖的方法时,B 甚至不存在,所以它调用 A' 版本的方法.但是,我不确定为什么我在 Java 和 C#(来自 C++)中得到不同的行为
I realize that in C++ objects are created from top-most parent going down the hierarchy, so when the constructor calls the overridden method, B does not even exist, so it calls the A' version of the method. However, I am not sure why I am getting different behavior in Java and C# (from C++)
推荐答案
在 C++ 中,正如您正确指出的那样,对象的类型是 A
直到 A
构造函数是完成的.对象在构造过程中实际上改变了类型.这就是使用 A
类的 vtable 的原因,所以 A::foo()
被调用而不是 B::foo()
.
In C++, as you correctly noted, the object is of type A
until the A
constructor is finished. The object actually changes type during its construction. This is why the vtable of the A
class is used, so A::foo()
gets called instead of B::foo()
.
在 Java 和 C# 中,自始至终都使用最派生类型的 vtable(或等效机制),即使在基类的构造过程中也是如此.所以在这些语言中,B.foo()
会被调用.
In Java and C#, the vtable (or equivalent mechanism) of the most-derived type is used throughout, even during construction of the base classes. So in these languages, B.foo()
gets called.
请注意,一般不建议从构造函数中调用虚方法.如果您不是很小心,虚拟方法可能会假定对象是完全构造的,即使情况并非如此.在 Java 中,每个方法都是隐式虚拟的,您别无选择.
Note that it is generally not recommended to call a virtual method from the constructor. If you're not very careful, the virtual method might assume that the object is fully constructed, even though that is not the case. In Java, where every method is implicitly virtual, you have no choice.
这篇关于从父类ctor调用重写的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从父类ctor调用重写的方法
- 获取数字的最后一位 2022-01-01
- 转换 ldap 日期 2022-01-01
- GC_FOR_ALLOC 是否更“严重"?在调查内存使用情况时? 2022-01-01
- 将 Java Swing 桌面应用程序国际化的最佳实践是什么? 2022-01-01
- java.lang.IllegalStateException:Bean 名称“类别"的 BindingResult 和普通目标对象都不能用作请求属性 2022-01-01
- Eclipse 的最佳 XML 编辑器 2022-01-01
- 如何使 JFrame 背景和 JPanel 透明且仅显示图像 2022-01-01
- 如何指定 CORS 的响应标头? 2022-01-01
- 在 Java 中,如何将 String 转换为 char 或将 char 转换 2022-01-01
- 未找到/usr/local/lib 中的库 2022-01-01