我听到(并在该站点上阅读了)很多关于“偏重于继承而非继承”的内容。
但是什么是Compositon?我从人:哺乳动物:动物的角度理解继承,但是我真的看不到任何地方的“组成”的定义。
Answers:
组合是指将简单类型组合为更复杂的类型。在您的示例中,组成可能是:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person::Mammal:
string firstName
string lastName
如果您想完全合成(并摆脱所有继承),它将看起来像这样:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person:
private Mammal _mammalRef
string firstName
string lastName
这种方法的优点是类型Mammal
和Person
不必符合其先前父级的接口。这可能是一件好事,因为有时对超类的更改可能会对子类产生严重影响。他们仍然可以通过这些类的私有实例来访问这些类的属性和行为,如果他们想公开这些以前的超类行为,则可以将它们简单地包装在一个公共方法中。
我在此处找到了包含示例的良好链接:http : //www.artima.com/designtechniques/compoinh.html
w69rdy
,稍后再回答。是的,我可以这么说。
组成只是组成整体的部分。汽车具有车轮,发动机和座椅。继承是一个“是”关系。作文是一种“有”的关系。
class Engine
{
}
class Automobile
{
}
class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here
}
组成-对象的功能由不同类的集合组成。实际上,这意味着持有一个指向要延迟工作的另一个类的指针。
继承-对象的功能由其自身的功能以及其父类的功能组成。
至于为什么首选组合而不是继承,请看一下Circle-ellipse问题。
Composition的一个示例是在另一个类中有一个类的实例,而不是从该类继承
此页面有一个很好的文章,解释为什么人们说:“在继承青睐组成”用的,为什么一些例子。
组成
只是意味着使用引用其他对象的实例变量。
1-通过继承进行编码
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
当您运行时Example1 application
,它会打印出“ Peeling具有吸引力。”,因为Apple继承(重复使用)Fruit的实现peel()
。但是,如果将来希望将的返回值更改为peel()
Peel类型,则会破坏的代码Example1
。即使Example1直接使用Apple且从未明确提及Fruit,您对Fruit的更改也会破坏Example1的代码。有关更多信息,请参考以下内容:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
//...
}
class Fruit {
// Return a Peel object that
// results from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
// Apple still compiles and works fine
class Apple extends Fruit {
}
// This old implementation of Example1
// is broken and won't compile.
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
2-通过组合
编写代码组合提供了一种Apple
重复使用的Fruit's
实现的替代方法peel()
。除了扩展外Fruit
,Apple
还可以保留对Fruit
实例的引用,并定义自己的peel()
方法,该方法仅对peel()
Fruit调用。这是代码:
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
有关更多信息,请 参考
Class A
内部对象Class B
(而不是Class B
从中继承子类时Class A
)。” ?