2012-08-06 74 views
7

请考虑我有一些摘要Vehicle类和汽车,卡车,摩托车抽象类派生从Vehicle。另外想象一下,我必须能够为卡车和摩托车制造基于燃料的汽车或电动汽车等。 (具体类)我怎样才能制作一个不同签名的多态方法

两个问题:

1.Consider,我想填补能量的车辆不知道它是什么,在一个多态的方式。例如,如果车辆燃料为基础的我想与燃料填充和方法应符合3个参数:
void FillUpEnergy(EfuelType i_fuelType,int amounOfEnergy, int maxAmountOfEnergy)

但基于electricy车辆,我需要几乎同样的功能signture但这次没有燃料类型当然,例如(2个参数):

void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy) 

我可以做一个polymorhic FillUpEnergy方法与上述限制? (不同方法的签名)

2.In我实现所有的具体类保持Engine代表一个FuelEngineElectricEngine(其它具体的类我有一个从发动机派生)的参考(另一个抽象类)。例如,我有一个名为ElectricCar的具体类,其中包含ElectricEngine的参考。
这个架构是否足够好或者有更好的方法来实现车库系统? (在面向对象的设计等方面)

+1

我不太拿到1)对于2),这就是所谓的桥,它的设计模式之一。 – 2012-08-06 21:44:15

+0

桥梁模式是我的第一个想法。 – 2012-08-06 22:06:44

回答

8

你不能让一个多态的“推式”方法有不同的签名,但你可以使用广为人知的Visitor Pattern做多态“拉风”的方法。

的想法是反转相互作用的序列,并让汽车对象决定做什么:与其说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
+2

不错的答案!虽然 – dash 2012-08-06 21:54:14

+1

虽然错过了旧的头像,但是这里的访客不是不必要的复杂吗?关于采取电力和采取任何其他类型的燃料听起来像一样的概念... – 2012-08-06 22:00:09

+0

@塞巴斯蒂安你对访客模式是绝对正确的:它可以很容易失控,特别是如果你需要保持可扩展性。但是对于可以预先指定的层次结构(比如这个层次结构),这不应该是一个大问题:只有少数几种方法,在头脑中进行交互仍然很容易。就用燃气和电力来加油是一个概念而言,我认为这种设计反映了通过提供单一的“FillUpEnergy”方法。 – dasblinkenlight 2012-08-06 22:12:55

3

关于问题1)

你可以使fueltype的电动/汽油一部分,并在你的域逻辑处理这个问题。

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

2)被称为组成

0
  1. 你不能这样做,因为这将是完全违反封装。
  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); 

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

0

关于1)
FillUpEnergy多态性(subtype polymorphism的点)是能够调用此方法时,你唯一知道的是,对象是Vehicle

如果您需要知道确切的类型以便选择正确的参数集,那么它们不需要此功能是多态的。

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