如何使用不同的签名创建多态方法

时间:2012-08-06 21:40:32

标签: c# oop inheritance polymorphism

考虑我有一些抽象 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的引用 这种架构是否足够好或是否有更好的方法来实施车库系统? (在面向对象设计等方面。)

5 个答案:

答案 0 :(得分:8)

您无法使用不同的签名制作多态“推式”方法,但您可以使用广为人知的Visitor Pattern制作多态“拉式”方法。

这个想法是颠倒交互的顺序,让汽车对象决定做什么:不要打电话给你FillUpEnergy给汽车你想要的东西,而是叫{ {1}}让汽车采取它所需要的东西,如下所示:

FillUpEnergy

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

  • 您致电interface IEnergyProvider { void TakeFuel(EfuelType i_fuelType, int amounOfEnergy); void TakeElectricity(int amounOfEnergy); } interface ICar { void FillUpEnergy(IEnergyProvider provider); }
  • 汽车拨打myCar.FillUpEnergy(myProvider)myProvider.TakeFuel

答案 1 :(得分:3)

关于问题1)

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

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

2)被称为Composition

答案 2 :(得分:1)

ElectricCarFueledCar的区别是什么?除了引擎(概念上)之外别无其他:

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填充燃料时命名有点奇怪......但这不是重点。

答案 3 :(得分:0)

  1. 你不能那样做,因为这完全违反了封装。
  2. 我不明白你关于发动机的问题,但我可以肯定地说,可能有很多更好的方法来实施“车库系统”,因为有很多不同的“车库系统”。这实际上意味着您不应该尝试对系统建模(根据OOP或任何其他条款),直到您充分了解您的要求为止。

答案 4 :(得分:0)

关于1)
拥有FillUpEnergy多态(subtype polymorphism)的要点是,当您知道的唯一对象是Vehicle时,才能调用此方法。

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

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