9

考虑我有一些抽象 Vehicle类和汽车、卡车、摩托车抽象类,它们派生自Vehicle. 还想象一下,我必须能够为卡车和摩托车创造一辆基于燃料的汽车或电动汽车等等。(具体类)

两个问题:

1.考虑我想在不知道它是什么的情况下以多态方式在车辆中填充能量。例如,如果车辆是基于燃料的,我想用燃料填充它,该方法应该使用 3 个参数:
void FillUpEnergy(EfuelType i_fuelType,int amounOfEnergy, int maxAmountOfEnergy)

但是对于基于电动的车辆,我需要几乎相同的功能签名,但这次当然没有燃料类型,例如(2个参数):

void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy) 

我可以FillUpEnergy用上述约束做一个多态方法吗?(不同方法的签名)

2.在我的实现中,所有具体类都为Engine(另一个抽象类)提供一个引用,它代表一个FuelEngineElectricEngine(我拥有的其他从引擎派生的具体类)。例如,我有一个名为的具体类ElectricCar,其中包含ElectricEngine.
这种架构足够好还是有更好的方法来实现车库系统?(在面向对象设计等方面。)

4

5 回答 5

10

您不能使用不同的签名创建多态“推式”方法,但可以使用广为人知的访问者模式创建多态“拉式”方法。

这个想法是颠倒交互的顺序,让汽车对象决定做什么:与其调用FillUpEnergy汽车你认为它需要的东西,不如调用FillUpEnergy并让汽车接受它知道它需要的东西,如下所示:

interface IEnergyProvider {
    void TakeFuel(EfuelType i_fuelType, int amounOfEnergy);
    void TakeElectricity(int amounOfEnergy);
}
interface ICar {
    void FillUpEnergy(IEnergyProvider provider);
}

现在你的多态方法的签名是固定的,但是方法的调度需要两条腿而不是一条腿:

  • 你打电话myCar.FillUpEnergy(myProvider)
  • 汽车呼叫myProvider.TakeFuelmyProvider.TakeElectricity
于 2012-08-06T21:52:59.263 回答
4

关于问题1)

您可以将电动/汽油作为燃料类型的一部分,并在您的域逻辑中处理它。

C# 不提供具有不同签名的多态性。

2) 称为组合

于 2012-08-06T21:44:32.883 回答
2

ElectricCar与有什么区别FueledCar?只有引擎(概念上):

interface IEngine
{
    void FillUpFuel(int amountOfFuel, int maxAmountOfFuel);
}

class ElectricEngine : IEngine
{
    public void FillUpFuel(int amountOfFuel, int maxAmountOfFuel) { ... }
}

abstract class Vehicle
{
    public abstract IEngine Engine { get; }
}

class Car : Vehicle
{
    public IEngine _engine;
    public override IEngine Engine { get { return _engine; } }

    public Car(IEngine engine)
    {
        _engine = engine;
    }
}
...
var electricCar = new Car(new ElectricEngine());
electricCar.Engine.FillUpFuel(40, 70);

典型的组合与继承示例。命名与 ElectricEngine 填充燃料有点奇怪……但这不是重点。

于 2012-08-06T21:52:10.853 回答
0

关于 1)
具有FillUpEnergy多态性(子类型多态性)的要点是能够在您唯一知道的是对象是 a 时调用此方法Vehicle

如果您需要知道确切的类型以选择正确的参数集,那么他们不需要这个函数是多态的。

关于 2)
没有什么令人震惊的

于 2012-08-06T21:52:41.427 回答
-1
  1. 你不能这样做,因为这完全违反了封装。
  2. 我不明白你关于引擎的问题,但我可以肯定地说,可能有很多更好的方法来实现“车库系统”,因为有这么多不同的“车库系统”。这实际上意味着您不应该尝试对系统建模(根据 OOP 或任何其他术语),直到您很好地掌握了您的需求。
于 2012-08-06T21:47:23.980 回答