Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建具有不同签名的多态方法_C#_Oop_Inheritance_Polymorphism - Fatal编程技术网

C# 如何创建具有不同签名的多态方法

C# 如何创建具有不同签名的多态方法,c#,oop,inheritance,polymorphism,C#,Oop,Inheritance,Polymorphism,假设我有一些抽象的

假设我有一些抽象的
类和从
车辆
派生的汽车、卡车、摩托车抽象类。还可以想象,我必须能够为卡车和摩托车制造一辆燃料汽车或电动汽车等等。(混凝土类)

两个问题:

考虑到我想用一种多态的方式来填充车辆中的能量而不知道它是什么。例如,如果车辆以燃油为基础,我想给它加注燃油,并且该方法应具有3个参数:
void FillUpEnergy(EfuelType i_fuelType,int-amounOfEnergy,int-maxAmountOfEnergy)

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

我可以使用上述约束条件执行polymorhic
FillUpEnergy
方法吗?(不同方法的签名)

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

关于问题1)

您可以将电力/汽油作为fueltype的一部分,并在您的域逻辑中处理它

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

2) 这就是作文

  • 您不能这样做,因为这完全违反了封装
  • 我不理解你关于发动机的问题,但我可以肯定地说,可能有很多更好的方法来实施“车库系统”,因为有这么多不同的“车库系统”。这实际上意味着您不应该尝试对您的系统进行建模(根据OOP或任何其他术语),直到您很好地掌握了您的需求

  • 什么是
    电动汽车
    燃油汽车
    的区别?只有引擎(概念上):

    典型的组合与继承示例。命名有点奇怪,因为发动机正在加油。。。但这不是重点。

    关于1)
    拥有
    FillUpEnergy
    polymorphic()的意义在于,当您只知道对象是
    Vehicle
    时,就能够调用此方法

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

    大约2)

    没有什么令人震惊的

    你不能用不同的签名制作多态的“推式”方法,但是你可以用广为人知的方法制作多态的“拉式”方法

    想法是颠倒交互顺序,让汽车对象决定做什么:不要调用
    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.TakeFuel
      myProvider.takeelectronic

    我不太明白1)至于2),它叫Bridge,是设计模式之一。Bridge模式也是我的第一个想法。回答得好!想念老阿凡达,但这里的访客不是不必要的复杂吗?关于用电和其他燃料听上去是同一个概念…@Sebastian你对访问者模式的看法绝对正确:它很容易失控,特别是如果你需要保持可扩展性的话。但是,对于可以预先指定的层次结构,比如这个层次结构,这应该不是什么大不了的事情:只有少数几种方法,在你的脑海中穿行交互仍然很容易。至于汽油和电力的燃料是同一个概念,我认为设计通过提供单一的
    填充能量
    方法反映了这一点。在这种情况下,汽车是聚合根。正如德米特定律所说,你们不应该单独使用引擎,只能通过汽车物体。这里的灌木丛完全被打破了。
    
    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);
    
    interface IEnergyProvider {
        void TakeFuel(EfuelType i_fuelType, int amounOfEnergy);
        void TakeElectricity(int amounOfEnergy);
    }
    interface ICar {
        void FillUpEnergy(IEnergyProvider provider);
    }