1. 程式人生 > >java-組合優於繼承

java-組合優於繼承

組合和繼承,都能實現對類的擴充套件。

區別如下表所示

組合
繼承
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.考慮複用父類方法,而且父類很少改動,可以用繼承。
其他情況請慎重使用繼承。