c#多态性。从基类转换为派生

时间:2016-10-28 15:59:03

标签: c# polymorphism

我对C#中的这一小段代码有疑问(假设函数ManageCars在MainProgram中)。 代码应该可行,但我的问题是:这是使用多态的正确方法吗?从Car转投法拉利是不正确的还是编程方式不好?我发现的唯一问题是我需要一个很长的开关/箱来管理所有类型(法拉利,梅赛德斯......)。 你有什么看法?

class Car
{
    string _plate = "";

    public string Plate
    {
        get { return _plate; }
        set { _plate = value; }
    }

}
class Ferrari : Car
{
    string specialName = "";

    public string SpecialName
    {
        get { return specialName; }
        set { specialName = value; }
    }

    Ferrari (Car obj )
    {
        specialName = (obj is Ferrari) ? ((Ferrari)obj).SpecialName : "";
    }
}

static void ManageCars (Car A)
{
    if (A is Ferrari) 
    {
        Ferrari B= (Ferrari) A;
        Console.Writeline("This is a Ferrari! specialName is " + B.SpecialName);
    }
    //else if(A is Mercedes)
    //{
            ...
    //}
    else
    {
        Console.Writeline("This is simple car");
    }
}

3 个答案:

答案 0 :(得分:1)

在课堂上,您应该创建如下虚拟函数:

public virtual void ManageCars()
{
    Console.Writeline("This is simple car");
}

所有派生类都可以通过覆盖基类方法来实现派生功能。例如:

public override void ManageCars()
{
    Console.Writeline("This is a Ferrari! specialName is " + B.SpecialName);
}

然后,对于每辆派生汽车,您只需调用ManageCars,无需任何开关声明。

答案 1 :(得分:1)

我建议不要在这种情况下使用多态性。你最终会得到很多子类。创建一个汽车类,并添加诸如“制造”,“模型”,“颜色”,“马力”等属性。相信我,从经验来看,这将为您节省许多令人头疼的事。

话虽如此,是的,您可以使用“as”运算符来检查基类是否是子类的实例,但它通常表明架构是坏的。

答案 2 :(得分:1)

使用多态时,通常在需要检索特殊方法时使用从基类到专用类的转换。例如假设你有

public class Batmobile: Car 
{
   public void fly() 
   {
     // flying algo here
   }
}

然后,如果要迭代基类型的集合,并且需要在可能的情况下应用特殊行为,则可以从基类转换为专用类并调用特殊行为

例如:

Car[] cars = new Car[];
// Retrieve your cars collection here
foreach (Car car in cars)
{
   if (car is BatMobile)
   {
      BatMobile batCar = (BatMobile)car;
      batCar.fly();      // No way to invoke this method unless we are sure it's    
                         // a BatMobile

   }
}

但是在上面提到的情况下,最好利用虚拟方法调用和后期绑定来利用C#语言的多态能力。

如@Jonathan Riger所示,您创建了一个类似ManageCars的虚拟方法,然后在每种特殊类型的后代中覆盖它。凭借运行时的多态性,将使用来自基类的编译时调用从相应的实例调用正确的方法

例如

Car class中的

public virtual void ManageCars()
{
    Console.Writeline("This is simple car");
}

法拉利课程:

public override void ManageCars()
{
    Console.Writeline("This is a Ferrari! specialName is " + B.SpecialName);
}

在BatMobile类中:

public override void ManageCars()
{
    Console.Writeline("This is a BatMobile car, it can fly really high !");
}

现在假设我们有:

Car[] cars = new Car[3];
cars[0] = new Car();
cars[1] = new Ferrari();
cars[2] = new BatMobile();

如果循环遍历数组并调用ManageCar()方法,例如:

foreach (Car car in cars) 
{
   car.ManageCars();
}

...它将在运行时检索正确的方法,即使编译时调用是基于不知道方法特化的基类:它是多态性魔法的一部分:)