与面向对象设计相关的组合是什么?
我听到(并在这个网站上读到)很多关于“偏好组合优于继承”。
但什么是组合呢?我从人:哺乳动物:动物的角度理解继承,但我在任何地方都看不到组合的定义......
I hear (and read on this site) a lot about "favour composition over inheritance".
But what is composition? I understand inheritance from the point of Person : Mammal : Animal, but I can't really see the definition of composition anywhere...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
组合是指将简单类型组合成更复杂的类型。在您的示例中,组合可以是:
如果您想完全组合(并摆脱所有继承),它看起来像这样:
这种方法的优点是类型
Mammal
和Person
不必遵守其先前父级的接口。这可能是一件好事,因为有时对超类的更改可能会对子类产生严重影响。他们仍然可以通过这些类的私有实例来访问这些类的属性和行为,如果他们想公开这些前超类的行为,他们可以简单地将它们包装在公共方法中。
我在组合与继承中找到了一个很好的链接,其中包含很好的示例。比较两种关联类的基本方法。
Composition refers to combining simple types to make more complex ones. In your example, composition could be:
If you wanted to go totally composition (and get rid of all inheritance) it would look like this:
The advantage to this approach is that the types
Mammal
andPerson
do not have to conform to the interface of their previous parent. This could be a good thing because sometimes a change to the superclass can have serious effects on the subclasses.They still can have access to the properties and behaviours of these classes through their private instances of these classes, and if they want to expose these former-superclass behaviours, they can simply wrap them in a public method.
I found a good link with good examples in Composition versus Inheritance. A Comparative Look at Two Fundamental Ways to Relate Classes.
组合只是构成整体的部分。汽车有车轮、发动机和座椅。继承是一种“是”的关系。组合是一种“有”关系。
Composition is simply the parts that make up the whole. A car has wheels, an engine, and seats. Inheritance is a "is a " relationship. Composition is a "has a" relationship.
可以通过三种方式为类赋予行为。您可以将该行为写入类中;您可以从具有所需行为的类继承;或者您可以将具有所需行为的类作为字段或成员变量合并到您的类中。最后两种代表代码重用的形式,最后一种 - 组合 - 通常是首选。它实际上并没有为您的类提供所需的行为 - 您仍然需要在现场调用该方法 - 但它对您的类设计施加了更少的限制,并且使代码更容易测试和调试。继承有其一席之地,但组合应该是首选。
There are three ways to give behavior to a class. You can write that behavior into the class; you can inherit from a class that has the desired behavior; or you can incorporate a class with the desired behavior into your class as a field, or member variable. The last two represent forms of code reuse, and the final one - composition - is generally preferred. It doesn't actually give your class the desired behavior - you still need to call the method on the field - but it puts fewer constraints on your class design and results in easier to test and easier to debug code. Inheritance has its place, but composition should be preferred.
考虑:
组合 - 对象的功能由不同类的集合组成。实际上,这意味着持有一个指向另一个类的指针,该类的工作将被推迟。
继承 - 对象的功能由其自身的功能加上其父类的功能组成。
至于为什么组合优于继承,请查看圆椭圆问题 。
Consider:
Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.
Inheritance - Functionality of an object is made up of its own functionality plus functionality from its parent classes.
As to why composition is preferred over inheritance, take a look at the Circle-ellipse problem.
组合的一个示例是,您在另一个类中拥有一个类的实例,而不是从它继承。
此页面有一篇很好的文章解释了为什么人们说“更喜欢组合而不是继承”,并举了一些例子。
An example of composition is where you have an instance of a class within another class, instead of inheriting from it.
This page has a good article explaining why people say "favour composition over inheritance" with some examples of why.
组合
仅仅意味着使用引用其他对象的实例变量。
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:
1- 通过继承进行代码
当您运行
Example1应用程序
时,它将打印出“Peeling is吸引人。”,因为Apple继承(重用)了Fruit的peel实现()
。但是,如果在将来的某个时刻,您希望将peel()
的返回值更改为 Peel 类型,则将破坏Example1
的代码。即使Example1直接使用Apple并且从未明确提及Fruit,您对Fruit的更改也会破坏Example1的代码。欲了解更多信息参考
看起来像这样:
2- 通过组合编写代码
组合为
Apple
提供了一种重用Fruit
的peel()
实现的替代方法。Apple
可以保存对Fruit
实例的引用并定义自己的peel()
方法,而不是扩展Fruit
只需调用 Fruit 上的peel()
即可。这是代码:更多信息ref
composition
simply mean using instance variables that are references to other objects.
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:
1- Code via inheritance
When you run the
Example1 application
, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation ofpeel()
. If at some point in the future, however, you wish to change the return value ofpeel()
to type Peel, you will break the code forExample1
. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit.for more info ref
Here's what that would look like:
2- Code via composition
Composition provides an alternative way for
Apple
to reuseFruit's
implementation ofpeel()
. Instead of extendingFruit
,Apple
can hold a reference to aFruit
instance and define its ownpeel()
method that simply invokespeel()
on the Fruit. Here's the code:for more information ref