当前位置:  开发笔记 > 编程语言 > 正文

继承还是构成:依靠"is-a"和"has-a"?

如何解决《继承还是构成:依靠"is-a"和"has-a"?》经验,为你挑选了3个好方法。

当我设计类并且必须在继承和组合之间进行选择时,我通常使用经验法则:如果关系是"is-a" - 使用继承,如果关系是"has-a" - 使用组合.

总是对的吗?

谢谢.



1> Trumpi..:

不 - "是一个"并不总是导致继承.引用得很好的例子是正方形和矩形之间的关系.正方形是一个矩形,但设计从Rectangle类继承Square类的代码是不好的.

我的建议是用Liskov替换原则来增强你的"是一个/有一个"启发式.要检查继承关系是否符合Liskov替换原则,请询问基类的客户端是否可以在子类上运行,而不知道它在子类上运行.当然,必须保留子类的所有属性.

在正方形/矩形示例中,我们必须询问矩形的客户端是否可以在正方形上操作而不知道它是正方形.客户必须知道的是它在矩形上运行.以下函数演示了一个客户端,它假定设置矩形的宽度会使高度保持不变.

void g(Rectangle& r)
{
    r.SetWidth(5);
    r.SetHeight(4);
    assert(r.GetWidth() * r.GetHeight()) == 20);
}

这个假设适用于矩形,但不适用于正方形.因此该函数不能在一个正方形上运行,因此继承关系违反了Liskov Substitution原则.(顺便说一下 - 这个例子来自链接的文章.)


好的,它说明了这一点.但是,为什么广场会变成可变的?
每个人都听说过方形和矩形的问题,但是我从未真正遇到过这样的现实示例(我是初级开发人员,所以意义不大)。你能提供一个吗?
@John - 你的问题强调了遗传(因为它与Liskov替代原则有关)是关于行为的事实.如果方块不可变,则没有问题,因为没有客户端可以改变宽度或高度.
这是一个傻瓜.正方形可能是数学中的矩形,但如果将矩形定义为可以独立设置高度和宽度的四边形,则方形不适合.在这种情况下,矩形实际上通过具有两个不同边长的附加属性而不是仅一个来扩展为正方形.

2> cletus..:

是的,不是.

线条可以模糊.从OO早期的OO编程的一些非常可怕的例子来看,这没有得到帮助:经理是员工是人.

你必须记住的关于继承的事情是:继承打破了封装.继承是一个实现细节.有关这个主题的各种文章.

最简单的总结方法是:

喜欢成分.

这并不意味着将它用于完全排除继承.这只意味着继承是一种后备立场.


那么一个经理是一个员工就是一个员工_是一个人.你想说什么 ?

3> Federico A. ..:

如果关系是"is-a" - 使用继承,如果关系是"has-a" - 使用组合.总是对的吗?

从某种意义上说,是的.但是你必须小心不要引入不必要的,人为的"是一种"关系.

例如,有人可能认为ThickBorderedRectangle 是一个 Rectangle,初看起来似乎很合理,并决定使用继承.但是这种情况更好地描述了一个Rectangle 有一个边框,它可能是也可能不是ThickBorder.在这种情况下,他会更喜欢作曲.

以同样的方式,人们可能会认为ThickBorder 是一个特殊的边界并使用继承; 但是最好说边框宽度,因此更喜欢构图.

在所有这些模棱两可的案例中,我的经验法则是三思而后行,正如其他人所建议的那样,更喜欢构成而不是继承.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有