首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

《代碼大全》繼承反例討論:空覆蓋方法暗示設計缺陷,組合優於繼承

     編輯:程式設計綜合問答

原文場景

Cat 類有 Scratch(),派生 ScratchlessCat 覆蓋為空。書中建議:在 Cat 中引入 Claw 組件,Cat 包含 Claw,有爪子才能抓。

解讀

作者意在說明:繼承表達「是一種」關係,若子類行為與父類根本衝突(如貓不抓),說明父類假設過強(所有貓都能抓)。正確建模應將可變行為抽離為組件(Claw),父類持有組件引用,行為委托給組件。

代碼對比


// 繼承方式(脆弱)
class Cat { void scratch() { ... } }
class ScratchlessCat extends Cat { void scratch() {} } // 空實現,違反里氏替換原則

// 組合方式(靈活)
interface Claw { void scratch(); }
class RealClaw implements Claw { void scratch() { ... } }
class NoClaw implements Claw { void scratch() {} } // 空實現隔離在組件
class Cat { Claw claw; Cat(Claw c) { this.claw = c; } void scratch() { claw.scratch(); } }
// 使用
Cat normal = new Cat(new RealClaw());
Cat noScratch = new Cat(new NoClaw());

工程實踐觀點

  • 空覆蓋在框架/模板方法模式中常見(如 onCreate() 默認空實現),不一定是錯誤。
  • 關鍵在於語義:若空實現意味著「不支持該操作」,應拋出 UnsupportedOperationException 或用組合建模能力差異。
  • 《代碼大全》觀點偏向領域建模純粹性,實際工程中需權衡複雜度與靈活性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved