一般理解多态(c#示例)

时间:2014-07-22 19:33:34

标签: c# polymorphism override abstract-class

我目前正在自学一些C#的基本概念,我正在尝试抽象类和多态。我以为我得到了基本概念,但事实证明这个概念不像我理解的那样工作:)。但是 - 我希望我得到一些清除灰尘的答案:)。

我想要实现的整个任务是扩展一个抽象基类,并使用带有基类对象的扩展。像这里:

我有一个抽象类,它实现了一个抽象属性,如:

public abstract class BaseClass
{
   public abstract MyProperty mP{get;}
}

属性为

public abstract class MyProperty 
{
   public abstract string PropertyName{get;}
}

现在我正在为像

这样的实际实现派生MyProperty类
public class DerivedProperty : MyProperty
{
  public override string PropertyName
  {
    get
    {
      return this._name;
    }
  }

  private _name = "Property1";

 /* some other implementation follows here...... */
}

由于我已经理解了多态性和继承,现在应该可以从BaseClass实例化派生类,并使用DerivedProperty对象覆盖属性MyProperty,如下所示:

public class DerivedClass : BaseClass
{
  public override DerivedProperty mP
  {
    get
    {
      return dP;
    }
  }

  private DerivedProperty dP = new DerivedProperty();

  /* more implementation follows here...... */
}

因为DerivedProperty同时是MyProperty和DerivedProperty的对象,所以可以在引用MyProperty或DerivedProperty的地方使用它。至少这是我的想法,但似乎这是错误的。 现在我想知道 - 为什么当上面的东西不可能时,多态如此有用?因为即使我尝试这样的事情:

public class DerivedClass : BaseClass
{
  public override MyProperty mP
  {
    get
    {
      return dP as DerivedProperty;
    }
  }

  private DerivedProperty dP = new DerivedProperty();

  /* more implementation follows here...... */
}

我仍然只获得我的基础对象MyProperty而不是我想要得到的扩展对象DerivedProperty。 我知道为什么我会得到这些结果 - 我对我来说似乎不合逻辑:)。是真的像多态性应该工作还是我的实现只是废话而我必须以不同的方式来获取我的扩展属性?

在这里感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您必须为覆盖的财产提供相同的类型。您可以稍后在抽象BaseClass中使用它。覆盖时,参数以及成员的返回值必须相同。这通常不是问题。

我准备了以下示例,我的代码与您的代码类似。

在某些情况下,我看到添加了第二个属性,其中包含更具体的类型和更具体(更具体)的名称:

public abstract class BaseCar
{
    public abstract BaseDriver Driver { get; }
}

public abstract class BaseDriver
{
    public abstract string Name { get; set; }
}

public class AgressiveDriver : BaseDriver
{
    public override string Name { get; set; }
}

public class FastCar : BaseCar
{
    private AgressiveDriver _agressiveDriver = new AgressiveDriver();

    public override BaseDriver Driver { get { return _agressiveDriver; } }
    public AgressiveDriver AgressiveDriver { get { return _agressiveDriver; } }
}

第二种方法是使用泛型:

public abstract class BaseCar<TDriver> 
    where TDriver : BaseDriver
{
    public abstract TDriver Driver { get; }
}

public abstract class BaseDriver
{
    public abstract string Name { get; set; }
}

public class AgressiveDriver : BaseDriver
{
    public override string Name { get; set; }
}

public class FastCar : BaseCar<AgressiveDriver>
{
    private AgressiveDriver _agressiveDriver = new AgressiveDriver();

    public override AgressiveDriver Driver { get { return _agressiveDriver; } }
}

但我认为第一种方法更好,因为创建/使用BaseCar对象没有问题(例如,要创建BaseCar&lt;&gt;变量,您必须指定类型参数)。此外,为更具体的属性创建更具体的名称也是有意义的。

答案 1 :(得分:0)

我认为你不需要额外的复杂性。您在抽象类中有一个抽象类。如果您只是学习/重新学习,那么您已经跳过了几个简单的步骤来理解。这是一个更简单的例子。

public abstract class Shape
{

   public abstract double GetArea();
   public abstract double Circumference();
}


public class Square: Shape
{
    public double width {get; set;}

    public override double GetArea()
    {
        return width * width;
    }

    public override Circumference()
    {
        return width * 4;
    }
}

您现在可以实例化Square或创建Circle Class,并且可以使用Shape的任何位置。