如何制作具有不同签名的多态方法

本文关键字:多态 方法 何制作 | 更新日期: 2024-11-07 20:04:22

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

两个问题:

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

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

void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy) 

我可以在上述约束下执行多食FillUpEnergy方法吗? (不同方法的签名)

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

如何制作具有不同签名的多态方法

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

这个想法是颠倒交互的顺序,让汽车对象决定做什么:与其调用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

关于问题 1)

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

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

2)称为组合

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);

典型的组合与继承示例。命名有点奇怪,电动发动机加满燃料......但这不是重点。

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

如果您需要知道确切的类型才能选择正确的参数集,则此函数不需要是多态的。

约2)
没有什么令人震惊的

  1. 你不能这样做,因为这完全违反了封装。
  2. 我不明白你关于发动机的问题,但我可以肯定地说,可能有很多更好的方法来实施"车库系统",因为有这么多不同的"车库系统"。这实际上意味着,在你很好地掌握了你的需求之前,你不应该尝试对你的系统进行建模(在OOP或任何其他术语方面)。