组合
组合关系概述
- 实现类的复用除了继承外,还可以使用
组合
的方式,把该类当成另一个类的组合成分
,从而允许新类直接复用该类的public方法
。 - 不管继承还是组合,都允许在新类(对于继承就是子类)中直接复用旧类的方法。
- 组合是把
旧类对象作为新类的成员变量
组合起来,用以实现新类的功能
,用户看到的是新类的方法,而不能看到被组合对象的方法。因此,通常要在新类里使用private修饰被组合的旧类对象
。
组合和继承
-
从类的复用角度看,父类的功能等同于组合中被组合的类,都将自身的方法提供给新类使用;子类和组合关系里的整体类,都可复用原有类的方法,用于实现自身的功能。
-
继承关系中从多个子类抽象出共有父类的过程,类似于组合关系中多个整体类里提取被组合类的过程;继承关系中从父类派生子类的过程,则类似于组合关系中被组合类组合到整体类的过程。
-
使用继承实现: ``` class Animal {
private void beat() {
System.out.println(“心脏跳动…”);
}
public void breath() {
beat();
System.out.println(“吸一口气,吐一口气,呼吸中…”);
}
}
// 继承Animal,直接复用父类的breath()方法
class Bird extends Animal {
public void fly() {
System.out.println(“我在天空自在的飞翔…”);
}
}
// 继承Animal,直接复用父类的breath()方法
class Wolf extends Animal {
public void run() {
System.out.println(“我在陆地上的快速奔跑…”);
}
}
public class InheritTest {
public static void main(String[] args) {
Bird b = new Bird();
b.breath();
b.fly();
Wolf w = new Wolf();
w.breath();
w.run();
}
}
1 |
|
class Animal {
private void beat() {
System.out.println(“心脏跳动…”);
}
public void breath() {
beat();
System.out.println(“吸一口气,吐一口气,呼吸中…”);
}
}
class Bird {
// 将原来的父类组合到原来的子类,作为子类的一个组合成分
private Animal a;
public Bird(Animal a) {
this.a = a;
}
// 重新定义一个自己的breath()方法
public void breath() {
// 直接复用Animal提供的breath()方法来实现Bird的breath()方法。
a.breath();
}
public void fly() {
System.out.println(“我在天空自在的飞翔…”);
}
}
class Wolf {
// 将原来的父类组合到原来的子类,作为子类的一个组合成分
private Animal a;
public Wolf(Animal a) {
this.a = a;
}
// 重新定义一个自己的breath()方法
public void breath() {
// 直接复用Animal提供的breath()方法来实现Wolf的breath()方法。
a.breath();
}
public void run() {
System.out.println(“我在陆地上的快速奔跑…”);
}
}
public class CompositeTest {
public static void main(String[] args) {
// 此时需要显式创建被组合的对象
Animal a1 = new Animal();
Bird b = new Bird(a1);
b.breath();
b.fly();
// 此时需要显式创建被组合的对象
Animal a2 = new Animal();
Wolf w = new Wolf(a2);
w.breath();
w.run();
}
} ```
何时使用组合或者继承
组合
是”有 has-a
“关系,继承
是”是 is-a
“关系。- 比如
Dog和Animal类
应该使用继承
关系,因为用一个动物组合成一个狗毫无意义,狗不是由动物组成的,反而狗是动物(is-a关系)
; - 比如
Person类和Head类
就应该使用组合
关系,因为一个人由头组合(has-a关系)
,而不是头是人。
- 比如