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

Java 面向對象實戰:從重複代碼到繼承多態的打印機重構之路

     編輯:Java 綜合教學

Java 面向對象實戰:從重複代碼到繼承多態的打印機重構之路

面向對象設計的核心價值在於「應對變化」。本文透過打印機案例,展示如何從「複製貼上修修補補」演進至「繼承多態優雅擴展」,體現 OOP 核心思想。

階段一:單一打印機,硬編碼邏輯

class HPPrinter {
    void open() { System.out.println("Open"); }
    void print(String s) { System.out.println("print-->" + s); }
    void close() { System.out.println("Close"); }
}

class Test {
    public static void main(String[] args) {
        HPPrinter hp = new HPPrinter();
        hp.open(); hp.print("abc"); hp.close();
    }
}

問題:新增品牌需複製整個類別、修改主程式邏輯,違反開閉原則。

階段二:新增 Canon,條件判斷泛濫

class CanonPrinter {
    void open() { System.out.println("Open"); }
    void print(String s) { System.out.println("print-->" + s); }
    void close() { this.clean(); System.out.println("Close"); } // 差異點
    void clean() { System.out.println("Clean"); }
}

class Test {
    public static void main(String[] args) {
        int brand = 0; // 0=Canon, 1=HP
        HPPrinter hp = new HPPrinter();
        CanonPrinter canon = new CanonPrinter();
        
        if (brand == 1) { hp.open(); hp.print("abc"); hp.close(); }
        else { canon.open(); canon.print("123"); canon.close(); }
    }
}

問題:每新增品牌,主程式就要新增 if-else 分支,維護災難。

階段三:提取父類別,實現繼承複用

// 父類別:封裝共同行為
class Printer {
    void open() { System.out.println("Open"); }
    void print(String s) { System.out.println("Print-->" + s); }
    void close() { System.out.println("Close"); }
}

// 子類別:繼承共同行為,覆寫差異行為
class HPPrinter extends Printer {
    // 完全復用父類別,無需任何代碼
}

class CanonPrinter extends Printer {
    @Override
    void close() {
        this.clean();      // 子類別特有邏輯
        super.close();     // 呼叫父類別通用邏輯
    }
    void clean() { System.out.println("Clean"); }
}

階段四:主程式面向父類別程式設計(多態)

class Test {
    public static void main(String[] args) {
        int brand = 0;
        Printer printer; // 宣告父類別型別
        
        if (brand == 1) printer = new HPPrinter();
        else printer = new CanonPrinter();
        
        // 統一介面呼叫,具體行為由實際物件決定
        printer.open();
        printer.print(brand == 1 ? "abc" : "123");
        printer.close();
    }
}

核心設計模式對比

階段設計新增品牌成本主程式耦合度核心原則
一單一類別複製整類強耦合具體類—
二多類別+if-else新類+改主程式強耦合具體類—
三繼承體系新子類別依賴父類別開閉原則
四多態調用新子類別面向介面/父類里氏替換/依賴倒置

關鍵技術點解析

  1. 方法覆寫 (@Override):子類別重新定義父類別方法,實現差異化行為
  2. super 關鍵字:呼叫父類別被覆寫的方法,保留通用邏輯(Canon close → clean + super.close)
  3. 多態:父類別引用指向子類別物件,編譯期看父類別,執行期跑子類別
  4. 向上轉型:Printer p = new CanonPrinter(); 隱藏具體型別,暴露統一介面

進一步優化:工廠模式消除殘留 if-else

class PrinterFactory {
    public static Printer createPrinter(int brand) {
        switch (brand) {
            case 1: return new HPPrinter();
            case 0: return new CanonPrinter();
            default: throw new IllegalArgumentException("Unknown brand");
        }
    }
}

// 主程式完全無條件判斷
Printer printer = PrinterFactory.createPrinter(brand);
printer.open(); printer.print(...); printer.close();

總結

從「複製代碼」到「繼承多態」,再到「工廠封裝建立」,這條重構之路完美詮釋了面向對象設計精髓:

  1. 識別變化點:不同品牌的 close 行為不同
  2. 封裝不變點:open/print 通用邏輯上移父類別
  3. 面向抽象程式設計:主程式依賴 Printer 而非具體子類別
  4. 單一職責:各類別只負責自己的行為

這不只是語法練習,更是構建可維護、可擴展系統的思維訓練。下次面對「類似但不完全相同」的需求時,請先思考:什麼是共同的?什麼是不同的?如何用繼承與多態優雅表達?

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