Java继承与组合

继承是实现类复用的重要手段,但继承带来了一个坏处:破坏封装
组合也是实现类复用的重要方式,而组合可以提供良好的封装性。

本文包含以下内容

  1. 使用继承的注意点
  2. 利用组合实现复用

1. 使用继承的注意点

子类扩展父类时,子类可以从父类继承得到成员变量和方法。
如果访问权限允许,子类可以直接访问父类的成员变量和方法,相当于子类可以直接复用父类的成员变量和方法。
在这里插入图片描述
在继承中,父类的实现细节对子类不再透明,子类可以访问父类的成员变量和方法,并可以改变父类方法实现的细节(通过重写),从而导致子类可以恶意篡改父类的方法。

为了保证父类有良好的封装性,不会被子类随意改变,设计父类时应遵循如下规则:
在这里插入图片描述
以下程序示例:
在这里插入图片描述
在这里插入图片描述
在上面代码中:
在这里插入图片描述
如何把类设置为最终类,使其不能被继承?
在这里插入图片描述
何时需要从父类派生新的子类呢?
不仅需要保证子类是一种特殊的父类,还要具备以下两个条件之一:
在这里插入图片描述

2.利用组合实现复用

在这里插入图片描述
在继承中,子类可以直接获得父类的public方法,程序使用子类时,将可以直接访问改子类从父类那里继承到的方法。
而组合则是把旧类对象作为新类对象的成员变量组合进来,用以实现新类的功能,用户看到的是新类的方法,而不能看到被组合对象的方法,因此,通常在新类中使用private修饰被组合的旧类对象。

仅从类复用的角度来看,可以发现父类的功能等同于被组合的类,都将自身的方法提供给新类使用;子类和组合关系里的整体类,都可复原原有类的方法,用于实现自身的功能。

假设有三个类:Animal、Wolf 和 Bird,他们之间有如下所示的继承树:
在这里插入图片描述
上图所示的三个类的代码情况如下:
在这里插入图片描述
而在软件复用的角度来看,可将上面的三个定义改为如下形式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于这种情况的三个类,其对应的关系图如下所示:
在这里插入图片描述
这是组合实现复用的一种方式,wolf 对象和 Bird 对象由 Animal 对象组合而成,在上面程序中创建 Wolf 对象和Bird对象之前先创建 Animal 对象,并利用这个 Animal 对象来创建 Wolf 对象和 Bird 对象。

而对于这种情况的内存开销,有如下说明:
在这里插入图片描述
什么时候该用继承?什么时候该用组合呢?
继承是将一个抽象的类改造成能适用于某些特定需求的类。如Animal 和 Wolf
组合是如果两个类之间有明确的整体、部分的关系,例如Person 和 Arm(手臂)

总之
继承表达的是(is - a)关系
组合表达的是 (has - a)关系

猜你喜欢

转载自blog.csdn.net/JustDI0209/article/details/112005420
今日推荐