私の基本クラスには、基本クラスで初期化できないCar
フィールドが含まれています。engine
サブクラスでのみ初期化できます。たとえば、ElectricCar
i can write 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();
}
}
したがって、すべてのバージョンには長所と短所があります。どのバージョンが優れていますか? または、おそらく他の何かを提案することもできます。