【发布时间】:2012-10-13 12:35:33
【问题描述】:
我有两个对象的“血统”:
-
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()。所以:
- 这种方法有什么我没有发现的问题吗?
- 显然在构造函数中调用虚方法是不好的。我的情况是个例外吗?
【问题讨论】:
标签: c# inheritance