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

mir*_*iri 40 .net c# 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
}
Run Code Online (Sandbox Code Playgroud)

这好吗?据我所知,如果我不想覆盖它,我不必使用抽象属性.在这种情况下,它会没问题,只是方法Speak,Sleep等等应该是抽象的.

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

Tim*_*ora 74

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

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

使用override关键字覆盖成员.标记该成员,就sealed override好像它不应该再次被覆盖一样.

不要将属性标记为abstract或者virtual如果您不希望它被覆盖.

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

如何:定义抽象属性

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

看到:

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


Jon*_*nna 31

我知道我想让他们做什么,我不在乎他们是怎么做的:接口.

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

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

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

(顺便说一句,我不认为彼得是一种人类,但每个彼得都是人类的一个实例,恰好被称为彼得.以这种方式挑选示例代码并不公平,但是当你'重新考虑这类问题,它比平时更有针对性.

  • +1 - 同意,`Peter`应该是`Human`的子类的实例,例如`HumansWithTwoNames` (3认同)
  • @TimMedora是的,我们在编写示例代码时都会想到不好的名字,这通常无关紧要,但这是一个比大多数更重要的问题. (2认同)

Guf*_*ffa 14

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

如果您想创建一个虚拟属性,并希望它必须在继承您的类的类中被覆盖,那么您将使它成为一个抽象属性.

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

public abstract class Animal {

  public abstract bool CanBreathe { get; }

}
Run Code Online (Sandbox Code Playgroud)

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

public class Dog : Animal {

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

}

public class Fish : Animal {

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

}
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 7

当所有子类必须实现方法/属性时使用抽象。如果不需要每个子类都实现它,那么就不要使用它。

至于你的例子,如果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";
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

使Maker抽象的是正确的,因为每个车有一个制造商和需要能够分辨出谁是制造者是用户。