首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带继承的C#建模

带继承的C#建模
EN

Stack Overflow用户
提问于 2018-03-29 12:09:59
回答 2查看 448关注 0票数 1

为了简单起见,我把它转换成了Birds的例子:

让我们说,我们有鸟,有些会飞,有些不能,然而,它们都有翅膀,所有的飞鸟都是一样的。

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

另一个问题是,一只鸟需要翅膀才能飞翔,什么才能代表一种“需求-A”关系?从鸟类的角度来看,这将是一种“有-A”关系,但从表示飞行能力的模块来看,这将是一种“需要-A”关系。

这是我当前的类图。

为了解决上面的一些问题,我已经将鸟转换成由CanFlyBird继承的抽象类。这样做对吗?

因为在默认情况下,我似乎仍然需要弄清楚如何通过鸟类的翅膀来飞方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-29 12:22:40

我有建议,您可以取出继承链的CanFlyBird输出,而不是通过构造函数传递它,方法是利用组合,

所以它会变成

鸟继承给鹰和企鹅,你把CanFlyBird作为构造函数传递给鹰。

代码将是

代码语言:javascript
复制
interface IFly {
  void fly();
}

而CanFlyBird将是

代码语言:javascript
复制
   public class CanFlyBird : IFly {
     public void Fly() {}
   }

鹰将是

代码语言:javascript
复制
  public class Eagle : Bird {
     private readonly IFly _fly;
     public Eagle (IFly fly) {
        _fly = fly; 
     }
 }

我的建议是使用组合,而不是去贷款链的继承。

这样,如果我想对canFlyBird类进行变体,我可以在不更改现有类的情况下创建它。

所以它会变成Bird has a flying capability

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

您可以在CanFlyBird类中将fly方法作为虚拟方法,因此,如果有人想要重写它,该类可以重写其他使用基本版本的方法。

票数 1
EN

Stack Overflow用户

发布于 2018-03-29 12:22:18

你在正确的轨道上,但我认为你的第二个问题基本上是,“我如何确保我不能建造一只没有翅膀的鸟”。

“需要-A”关系仍然是“有-A”关系。您有两种实现需求的方法。

首先,可以在Bird中为您的属性创建一个默认值。

代码语言:javascript
复制
Wing wings = new Wing(); //as a field or
public Wing Wings { get; set; } = new Wing() //as a property

或者,在这种情况下,可能更正确地说,在构造函数中需要一个分支:

代码语言:javascript
复制
public Bird(Wing wing) { this.wings = wing; }

至于"Fly()“,我同意其他人的意见,并推荐了一种虚拟方法。您可以在以后的子类中重写这一点,如果有一天您决定将游泳算作飞行,允许您对企鹅子类进行最小的更改以实现您的更改。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49555676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档