首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

為什麼Java繼承有害(二):脆弱基類問題與接口替代方案

     編輯:Java 程式設計入門

脆弱基類實例:Stack與MonitorableStack

假設Stack繼承ArrayList實現,後發現性能不佳,重寫Stack改用數組+批量複製push_many()優化。但派生類MonitorableStack覆寫push()記錄高水位標記,因push_many()不再調用push(),導致監計邏輯失效。基類內部實現變更破壞派生類行為,且無法通過「小心」規避——這就是脆弱基類問題。

接口替代繼承:消除脆弱性

若Stack為接口,SimpleStack與MonitorableStack分別實現,代碼更健壯。接口強制實現類提供所有方法,無「繼承實現」耦合。復用通過組合/委派而非繼承:

interface Stack {
    void push(Object o);
    Object pop();
    void push_many(Object[] source);
}

class SimpleStack implements Stack {
    private int sp = -1;
    private Object[] stack = new Object[1000];
    public void push(Object o) { /* ... */ }
    public Object pop() { /* ... */ }
    public void push_many(Object[] src) {
        System.arraycopy(src, 0, stack, sp+1, src.length);
        sp += src.length;
    }
}

class MonitorableStack implements Stack {
    private Stack delegate = new SimpleStack();  // 組合
    private int highWaterMark = 0;
    public void push(Object o) {
        delegate.push(o);
        highWaterMark = Math.max(highWaterMark, size());
    }
    public void push_many(Object[] src) {
        delegate.push_many(src);
        highWaterMark = Math.max(highWaterMark, size());
    }
    // 其他方法委派給delegate...
}

雖需編寫委派樣板代碼,但消除了關鍵潛在Bug,成本極低。組合優於繼承,接口+委派實現同樣靈活的多態復用,卻避免了實現繼承的脆弱性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved