设计原则:多用组合,少用继承。
组合和继承,都能实现对类的扩展。
区别如下表所示:
组合 | 继承 |
---|---|
has-a关系 | is-a关系 |
运行期决定 | 编译期决定 |
不破坏封装,整体和局部松耦合 | 破坏封装,子类依赖父类 |
支持扩展,随意增加组合类 | 只能继承一个父类,必须包含所有方法,增加系统复杂性 |
动态选择组合类方法 | 复用父类方法 |
下面通过一个例子说明,子类继承必须包含所有父类方法,增加了出错率,修改父类方法会引起所有子类功能变化。
- /**
- * 呼叫基类
- *
- * @author peter_wang
- * @create-time 2014-5-20 下午4:30:33
- */
- public class SuperCallClass {
- public void call() {
- }
- public void operate1() {
- System.out.println("operate1 in super class");
- }
- public void operate2() {
- System.out.println("operate2 in super class");
- }
- /**
- * 冗余的函数,导致子类臃肿,破坏了封装,增加了出错机会
- */
- public void redundant() {
- System.out.println("redundant in super class");
- }
- }
- /**
- * 呼叫子类
- *
- * @author peter_wang
- * @create-time 2014-5-20 下午4:32:22
- */
- public class SubCallClass
- extends SuperCallClass {
- @Override
- public void operate1() {
- //破坏了封装,无意中引入了基类方法
- super.operate1();
- System.out.println("operate in sub class");
- }
- @Override
- public void call() {
- super.call();
- operate1();
- }
- }
- /**
- * 分析继承和组合
- *
- * @author peter_wang
- * @create-time 2014-5-20 下午4:37:31
- */
- public class CallClassDemo {
- /**
- * @param args
- */
- public static void main(String[] args) {
- SubCallClass subCallClass = new SubCallClass();
- subCallClass.operate1();
- }
- }
组合类的使用
- /**
- * 呼叫组合类
- *
- * @author peter_wang
- * @create-time 2014-5-20 下午5:11:34
- */
- public class CombineCallClass {
- private SuperCallClass mSuperCallClass;
- public CombineCallClass() {
- mSuperCallClass = new SuperCallClass();
- }
- public void operate1() {
- System.out.println("operate in combine class");
- }
- /**
- * 只需要使用到SuperCallClass中的operate2方法
- */
- public void operate2() {
- mSuperCallClass.operate2();
- }
- public void call() {
- operate1();
- }
- }
组合通常优于继承,
1.考虑使用多态,可以用继承。
2.考虑复用父类方法,而且父类很少改动,可以用继承。
其他情况请慎重使用继承。