考虑我有一些抽象 Vehicle
类以及来自Vehicle
的汽车,卡车,摩托车抽象类。还想象一下,我必须能够为卡车和摩托车制造基于燃料的汽车或电动汽车等。 (具体课程)
两个问题:
1.考虑到我想以多态的方式在不知道它是什么的情况下在车辆中填充能量。例如,如果车辆是基于燃料的,我想用燃料填充它,方法应该有3个参数:
void FillUpEnergy(EfuelType i_fuelType,int amounOfEnergy, int maxAmountOfEnergy)
但对于电动车辆,我需要几乎相同的功能,但这次当然没有燃料类型,例如(2个参数):
void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy)
我可以使用上述约束进行多态FillUpEnergy
方法吗? (不同方法的签名)
2.在我的实现中,所有具体类都包含Engine
(另一个抽象类)的引用,它代表FuelEngine
或ElectricEngine
(我从引擎派生的其他具体类) )。例如,我有一个名为ElectricCar
的具体类,它包含ElectricEngine
的引用
这种架构是否足够好或是否有更好的方法来实施车库系统?
(在面向对象设计等方面。)
答案 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)
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填充燃料时命名有点奇怪......但这不是重点。
答案 3 :(得分:0)
答案 4 :(得分:0)
关于1)
拥有FillUpEnergy
多态(subtype polymorphism)的要点是,当您知道的唯一对象是Vehicle
时,才能调用此方法。
如果你需要知道确切的类型以便选择正确的参数集,那么它们就不需要这个函数是多态的。
关于2)
没有什么是令人震惊的