提取子类通用的方法,但它使用子类特定类型

时间:2015-11-19 01:28:17

标签: c# oop inheritance

我有ElectricCarDieselCar类继承自Vehicle。 他们分别有ElectricEngineDieselEngine

两个引擎类都有Start方法。最初我在两个汽车子类中都实现了StartAllEngines(),但我发现它非常重复,所以我想在基类vehicle类中抽象它。

问题是,如何在基类中定义engines的类型? dynamic是一个选项,但我觉得使用它并不安全。

我不应该抽象方法?但是它违反了DRY原则。

public class Vehicle{
    protected List<???Engine> engines; // What should be the type?

    public void StartAllEngines (){
        foreach (???Engine engine in this.engines){
            engine.Start();
        }
    }
}

public class ElectricCar: Vehicle{
    public ElectricCar(){
        this.engines = List<ElectricEngine>();
    }
}

public class DieselCar: Vehicle{
    public DieselCar(){
        this.engines = List<DieselEngine>();
    }
}

public class ElectricEngine: Engine {...}
public class DieselEngine: Engine {...}

3 个答案:

答案 0 :(得分:1)

在基类w / Engine中使用泛型参数作为约束:

public class Vehicle<TEngine> where TEngine: Engine
{
    protected List<TEngine> engines = new List<TEngine>();

    public void StartAllEngines (){
        foreach (TEngine engine in this.engines){
            engine.Start();
        }
    }
}

public class ElectricCar: Vehicle<ElectricEngine>
{
    public ElectricCar(){
    }
}

public class DieselCar: Vehicle<DieselEngine>
{
    public DieselCar(){
    }
}

public class ElectricEngine: Engine {...}
public class DieselEngine: Engine {...}

答案 1 :(得分:1)

正如Plutonix所说,奇怪的是在基类中有一个引擎列表,没有任何意义

public class Vehicle{

    protected Engine engine;

    public void Start (){
        engine.Start();
    }
}

public class ElectricCar : Vehicle
{
    public ElectricCar(){
        engine = new ElectricEngine();
    }

    public void Start()
    {

    }
}

public class DieselCar: Vehicle
{

    public DieselCar(){
        engine = new DieselEngine();
    }
}

public class ElectricEngine : Engine
{
    public override void Start()
    {
        //Start Electric Engine
    }
}
public class DieselEngine: Engine {
    public override void Start()
    {
        //Start Diesel Engine
    }
}

public abstract class Engine
{
    //Alternatively use virtual, depending on what you want to achieve...
    public abstract void Start();
}

答案 2 :(得分:0)

您可以使用IEngine接口公开Start方法,然后由ElectricEngineDieselEngine

继承

例如

public interface IEngine
{
    void Start();
}

public class ElectricEngine : IEngine {

    public void Start()
    {
        // start code
    }
}

public class Vehicle{
    protected List<IEngine> engines;

    public void StartAllEngines (){
        foreach (IEngine engine in this.engines){
            engine.Start();
        }
    }
}