不确定何时使用抽象属性,何时不使用

时间:2012-09-03 21:54:20

标签: c# .net oop properties abstract

我不确定什么看起来更好,或者我什么时候在抽象类和属性中使用,或何时使用非抽象属性。我将尝试做一个简单的例子。假设我有这个:

abstract class Human
{
  public GenderType Gender { get; set; }
  public string Name { get; set; }
  public Date Born { get; set; }
  public bool IsNerd { get; set; }

  abstract public void Speak();
  abstract public void Sleep();
  abstract public void AnoyingPeopleOnStackOverflow();
  //... so on
}

class Peter : Human
{
  //Peter is special, he got a second name
  //But thats all, everything else is the same as like on other humans
  public string SecondName { get; set; }

  //...override abstract stuff
}

这样好吗?据我所知,如果我不想覆盖它,我不必使用抽象属性。在这种情况下,没关系,只有SpeakSleep等方法应该是抽象的。

现在,如果可以,我何时或应该使用抽象属性?

5 个答案:

答案 0 :(得分:71)

如果没有默认实现,并且派生类必须实现它,请使用抽象属性。

如果在基类中有实现但希望允许覆盖,请使用虚拟属性。

使用override关键字覆盖成员。如果成员不应再次被覆盖,请将该成员标记为sealed override

如果您不希望覆盖该属性,请不要将该属性标记为abstractvirtual

使用new关键字隐藏非抽象的非虚拟成员(这不是一个好主意)。

How to: Define Abstract Properties

我发现抽象属性经常出现在设计中,这意味着它们将具有特定于类型的逻辑和/或副作用。您基本上是在说,“这是一个所有子类必须具有的数据点,但我不知道如何实现它”。 然而,可能不需要包含大量逻辑和/或引起副作用的属性。这是一个重要的考虑因素,尽管没有固定的正确/错误的方法。

请参阅:

就个人而言,我发现我经常使用抽象方法但很少使用抽象属性。

答案 1 :(得分:27)

我知道我希望他们做什么,我不在乎他们是怎么做的:接口。

我知道我希望他们做什么,我不在乎他们是如何做的,但我对他们将如何(或至少大多数人)做其他事情有着坚定的想法:抽象类。

我知道我希望他们做什么,以及他们中的大多数人会这样做:具有虚拟成员的具体课程。

您可以使用其他案例,例如一个没有抽象成员的抽象类(你不能拥有一个实例,但是它提供了什么功能,它完全提供),但是它们通常是罕见的,因为特定的层次结构为一个给定的干净和公然提供了它问题

(顺便说一下,我不认为彼得是一种人类,但每个彼得都是人类的一个实例,恰好被称为彼得。以这种方式挑选示例代码并不公平,但是当你在思考这类问题时,它比平常更为恰当。)

答案 2 :(得分:13)

抽象成员只是您必须覆盖的虚拟成员。您将此用于必须实现的内容,但不能在基类中实现。

如果你想创建一个虚拟属性,并希望它必须在继承你的类的类中被覆盖,那么你可以将它作为一个抽象属性。

如果你有一个动物类,它的呼吸能力不可能只是从它的动物信息来确定,但它是非常重要的东西:

public abstract class Animal {

  public abstract bool CanBreathe { get; }

}

对于鱼和狗,实施方式会有所不同:

public class Dog : Animal {

   public override bool CanBreathe { get { return !IsUnderWater; } }

}

public class Fish : Animal {

   public override bool CanBreathe { get { return IsUnderWater; } }

}

答案 3 :(得分:4)

当所有子类具有以实现方法/属性时使用abstract。如果不需要每个子类来实现它,那么就不要使用它。

至于你的例子,如果每个人不需要SecondName,那么就不需要在基类中创建一个抽象属性。另一方面,如果每个人都需要第二个名字,那么将其作为一个抽象的财产。

正确使用抽象属性的示例:

public class Car
{
    public abstract string Manufacturer { get; }
}

public class Odyssey : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Honda";
         }
    }
}

public class Camry : Car
{
    public override string Manufacturer
    {
         get 
         {
             return "Toyota";
         }
    }
}

制作Maker摘要是正确的,因为每辆汽车都有制造商,并且需要能够告诉用户该制造商是谁。

答案 4 :(得分:1)

在您希望类始终公开属性的地方使用抽象属性,但是您无法确定该属性的实现方式 - 将其留给/强制继承类执行此操作。

有一个示例here,其中抽象类名为Shape,它公开了一个抽象的Area属性。您无法在基类中实现Area属性,因为区域的公式将针对每种类型的形状进行更改。所有形状都有一个区域(某种形状),因此所有形状都应该暴露属性。

您的实施本身看起来很好。试图为Human想出一个抽象属性的明智例子,却想不出任何合理的事情。