组合和继承。都能实现对类的扩展。
差别例如以下表所看到的
组合 | 继承 |
---|---|
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.考虑复用父类方法,并且父类非常少修改。能够用继承。
其它情况请谨慎使用继承。