c# – 如何初始化基类中应该在子类中初始化的字段?
发布时间:2020-12-15 04:24:29 所属栏目:百科 来源:网络整理
导读:我的基类Car包含无法在基类中初始化的字段引擎.我只能在子类中初始化它,例如在ElectricCar中我可以编写engine = new ElectricEngine.但是我在基类中使用了字段.所以我有一个使用但未初始化的字段: public class Car { protected Engine engine; public void
我的基类Car包含无法在基类中初始化的字段引擎.我只能在子类中初始化它,例如在ElectricCar中我可以编写engine = new ElectricEngine.但是我在基类中使用了字段.所以我有一个使用但未初始化的字段:
public class Car { protected Engine engine; public void Start() { engine.Start(); // do something else } public void Stop { engine.Stop(); // do something else } public void Diagnose() { engine.Diagnose(); // anotherField.Diagnose(); // oneAnotherField.Diagnose(); } } 如何更好地初始化引擎? 版本1.字段保证初始化但有许多字段构造函数看起来很难看.没有错误,但很难看. public class Car { protected Engine engine; public Car(Engine engine) { this.engine = engine; } public void Start() { engine.Start(); // do something else } public void Stop { engine.Stop(); // do something else } public void Diagnose() { engine.Diagnose(); // anotherField.Diagnose(); // oneAnotherField.Diagnose(); } } public class ElectricCar : Car { public ElectricCar() : base (new ElectricEngine()) { } } 版本2.子类应该记住初始化字段,与子类的这种“契约”可能会引入错误(未初始化的字段). public class Car { protected Engine engine; public Car() { } public void Start() { engine.Start(); // do something else } public void Stop { engine.Stop(); // do something else } public void Diagnose() { engine.Diagnose(); // anotherField.Diagnose(); // oneAnotherField.Diagnose(); } } public class ElectricCar : Car { public ElectricCar() { engine = new ElectricEngine(); } } 版本3.保证初始化字段.构造函数很清楚.但是从构造函数调用虚方法(有潜在危险,一般不推荐). public class Car { protected Engine engine; public Car() { InitializeEngine(); } protected abstract void InitializeEngine(); public void Start() { engine.Start(); // do something else } public void Stop { engine.Stop(); // do something else } public void Diagnose() { engine.Diagnose(); // anotherField.Diagnose(); // oneAnotherField.Diagnose(); } } public class ElectricCar : Car { public ElectricCar() { } protected void override InitializeEngine() { engine = new ElectricEngine(); } } 所以每个版本都有优点和缺点.哪个版本更好?或者你甚至可以建议别的东西. 解决方法
版本3是对
Template method design pattern的一种看法.如果你的基类不能提供合理的默认实现,但是你需要每辆汽车都有一个引擎,那么将创建委托给基类是一个非常合适和安全的解决方案.我会稍微调整你的初始化,如下所示:
protected abstract Engine InitializeEngine(); 然后在你的Car构造函数中: public Car() { engine = InitializeEngine(); } 这将使合同非常明确.您的子类只需要提供引擎,您的基类将保证在调用构造函数后分配引擎变量. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |