C#继承建模

时间:2018-03-29 12:09:59

标签: c# oop interface abstract-class

我正在努力模拟我遇到的问题,为简单起见,我已将其转换为Birds示例:

让我们说我们有鸟类,有些可以飞,有些可以,但是,它们都有翅膀,所有的飞鸟都以完全相同的方式飞行。

我的问题是什么更适合飞行能力?通常,使用接口来表示异能,但这需要我在每个Bird中实现Fly方法,尽管它们以相同的方式飞行。

另一个问题是,一只小鸟需要飞翔的翅膀,它可以代表一种“需要A"关系?它将是一个" Has-A"从鸟类的角度来看,但是从代表飞行能力的模块来看,它将是一个" Need-A"关系。

这是我目前的班级图。

Class Diagram

为了解决上述一些问题,我将Bird转换为CanFlyBird继承的抽象类。 这是正确的方法吗?

因为我似乎还需要弄清楚默认情况下如何将Bird Wings of Bird类传递给Fly方法。

Updated Class Diagram

2 个答案:

答案 0 :(得分:1)

你正走在正确的轨道上,但我认为你的第二个问题基本上是,"我怎样才能确保我不能构建一只无翅鸟?#34;。

" Need-A"关系仍然是一个" Has-A"关系。您有两种方法来实现该要求。

首先,您可以在Bird

中为您的媒体资源设定默认值
Wing wings = new Wing(); //as a field or
public Wing Wings { get; set; } = new Wing() //as a property

或者第二,在这种情况下可能更正确,在构造函数中需要Wing:

public Bird(Wing wing) { this.wings = wing; }

至于#34; Fly()"我同意其他人并推荐一种虚拟方法。您可以稍后在子类中覆盖它,如果您决定有一天将游泳计为飞行,则允许您对Penguin子类进行最小的更改以实现您的更改。

答案 1 :(得分:1)

我有建议,你可以取出继承链的CanFlyBird输出,而不是通过构造函数传递它,意味着使用组合,

所以它会变成

Bird继承了Eagle和Penguin,并将CanFlyBird作为构造函数参数传递给Eagle。

代码

interface IFly {
  void fly();
}

和CanFlyBird将是

   public class CanFlyBird : IFly {
     public void Fly() {}
   }

和鹰将

  public class Eagle : Bird {
     private readonly IFly _fly;
     public Eagle (IFly fly) {
        _fly = fly; 
     }
 }

我的建议是利用Composition而不是继承贷款链。

通过这种方式,如果我想制作canFlyBird类的变体,我可以在不改变现有类的情况下创建它

所以它会变成Bird has a flying capability

或者如果您想遵循当前结构,那么

你可以将fly方法作为CanFlyBird类中的虚方法,所以如果有人想覆盖它,那么该类可以覆盖其他使用基本版