我有两个对象的“谱系”:
Car
是一个基类SportsCar
Engine
是一个基类SportsEngine
Car
的字段之一是,engine
类型Engine
。SportsCar
覆盖它,而是有一个engine
类型为SportsEngine
.
的构造函数Car
有:
public Car() {
engine = new Engine();
}
的构造函数SportsCar
有:
public SportsCar() : base() {
engine = new SportsEngine();
}
这个想法是我有一个汽车类型的层次结构,每辆车都有一个合适的引擎(它决定了汽车功能的某些方面)。当我对汽车层次结构的某个点进行子类化时,我可以确定这辆车的发动机是否具有与现有汽车相同的马力、重量、燃料使用等,并使用现有发动机来填充该engine
字段。如果我决定我要添加的新车应该有一个独特的引擎,那么我可以Engine
继承层次结构来制作我的新引擎,然后我可以覆盖该engine
字段并更改我的新车的构造函数以正确初始化它。
问题是,如果我正确理解 C#,当我创建一个新B
的引擎实例时,将被初始化两次。严格来说,它并没有打破目前非常简单的情况。但是,会发生的是当我调用new SportsCar()
它时,它会首先执行engine = new Engine();
并且engine = new SportsEngine();
.
从概念上讲,当一辆跑车被制造出来时,你不会放入通用引擎,立即将其拉出,然后放入运动引擎,这就是我认为代码最终会做的事情。
实际上,当第一个结果被丢弃时,为什么要进行两次构造函数调用?
我的解决方案是调用virtual void CreateEngine() { engine = new Engine(); }
基础构造器,并且永远不要在儿童车中调用它。然后每辆车实现自己的override void CreateEngine()
. 所以:
- 这种方法有什么我没有看到的问题吗?
- 显然在构造函数中调用虚方法是不好的。我的情况是个例外吗?