继承和组合

    xiaoxiao2021-03-25  62

    继承和组合的区别

    假设有三个类:Animal,Wolf和Bird,继承关系如下代码所示:

    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(); } }

    这是很清晰的继承关系,Wolf和Bird对象都可以直接复用Animal的方法, 将上面的三个类改成如下形式也可以实现相同的复用:

    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(); } }

    此时,Wolf和Bird对象由Animal组合而成,运行程序可以得到与前面程序相同的执行结果。

    继承关系中从多个子类里抽象出共有父类的过程,类似于粗和关系中从多个整体类里提取被组合类的过程继承关系中从父类派生出子类的过程,类似于组合关系中把被组合类组合到整体类的过程。继承是对已有的类做一番改造,一次获得一个特殊的版本,也就是将一个较为抽象的类改造成能适用与某些特定需求的类。

    因此,对于上面的例子,使用继承更能表达其现实意义,用一个动物来合成一匹狼毫无意义:狼并不是由动物组成的。反之,如果两个类由明确的整体、部分的关系,例如Person需要复用Arm类的方法就应该采用组合关系来实现复用。

    继承表达的是(is a)的关系,而组合表达的是(has a)的关系

    转载请注明原文地址: https://ju.6miu.com/read-39152.html

    最新回复(0)