为了简单起见,我把它转换成了Birds的例子:
让我们说,我们有鸟,有些会飞,有些不能,然而,它们都有翅膀,所有的飞鸟都是一样的。
我的问题是什么更适合飞行能力?通常,能力是用接口表示的,但这需要我在每个鸟内实现Fly方法,尽管它们的飞行方式相同。
另一个问题是,一只鸟需要翅膀才能飞翔,什么才能代表一种“需求-A”关系?从鸟类的角度来看,这将是一种“有-A”关系,但从表示飞行能力的模块来看,这将是一种“需要-A”关系。
这是我当前的类图。

为了解决上面的一些问题,我已经将鸟转换成由CanFlyBird继承的抽象类。这样做对吗?
因为在默认情况下,我似乎仍然需要弄清楚如何通过鸟类的翅膀来飞方法。

发布于 2018-03-29 12:22:40
我有建议,您可以取出继承链的CanFlyBird输出,而不是通过构造函数传递它,方法是利用组合,
所以它会变成
鸟继承给鹰和企鹅,你把CanFlyBird作为构造函数传递给鹰。
代码将是
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;
}
}我的建议是使用组合,而不是去贷款链的继承。
这样,如果我想对canFlyBird类进行变体,我可以在不更改现有类的情况下创建它。
所以它会变成Bird has a flying capability
或者,如果您想遵循当前的结构,那么
您可以在CanFlyBird类中将fly方法作为虚拟方法,因此,如果有人想要重写它,该类可以重写其他使用基本版本的方法。
发布于 2018-03-29 12:22:18
你在正确的轨道上,但我认为你的第二个问题基本上是,“我如何确保我不能建造一只没有翅膀的鸟”。
“需要-A”关系仍然是“有-A”关系。您有两种实现需求的方法。
首先,可以在Bird中为您的属性创建一个默认值。
Wing wings = new Wing(); //as a field or
public Wing Wings { get; set; } = new Wing() //as a property或者,在这种情况下,可能更正确地说,在构造函数中需要一个分支:
public Bird(Wing wing) { this.wings = wing; }至于"Fly()“,我同意其他人的意见,并推荐了一种虚拟方法。您可以在以后的子类中重写这一点,如果有一天您决定将游泳算作飞行,允许您对企鹅子类进行最小的更改以实现您的更改。
https://stackoverflow.com/questions/49555676
复制相似问题