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

Java 介面繼承與抽象類別:設計多型契約的兩大支柱

     編輯:Java 程式設計入門

前言:從具體到抽象的架構演進

前幾章建立了類別繼承與封裝基礎。當系統增長,我們需要定義行為契約而非實作細節。介面與抽象類別是實現「面向介面程式設計」的兩大核心機制:前者定義**純粹契約**,後者提供**部份實作與共享狀態**。本章深入剖析兩者的語法、繼承規則、多重實作與設計抉擇。

一、介面繼承:契約的延伸與組合

1. 單一介面繼承:extends 關鍵字

介面可繼承另一介面,形成契約層級:

interface Cup {
    void addWater(int ml);
    void drinkWater(int ml);
}

// 延伸契約:加入刻度查詢
interface MetricCup extends Cup {
    int getWaterVolume(); // 新增方法簽名
}
MetricCup 繼承 Cup
MetricCup 擴展 Cup 契約,實作類別必須同時實作所有方法

2. 介面多重繼承:Java 介面獨有的威力

類別僅支援單繼承,但**介面可同時繼承多個父介面**,實現契約組合:

interface Player {
    void play();
    void pause();
}

interface Displayable {
    void display();
}

// 組合三大契約:容器、播放器、顯示器
interface MusicCup extends Cup, Player, Displayable {
    void setVolume(int level); // 專屬擴展
}

實作 MusicCup 的類別必須提供 **Cup + Player + Displayable + 自身** 的所有方法實作。這是 Java 介面相對類別繼承的巨大優勢——**契約可自由組合,不受單繼承限制**。

二、抽象類別:共享實作的骨架

1. 語法與核心規則

  • abstract class:宣告為抽象,**不可直接實例化**。
  • abstract method:無主體、無大括號、以分號結尾,**強制子類別實作**(除非子類別也為抽象)。
  • 可包含**非抽象方法**(具體實作)、**欄位**、**建構子**、**靜態成員**。
  • 含抽象方法的類別**必須**宣告為 abstract。
abstract class Food {
    // 共享欄位
    protected String name;

    // 建構子:供子類別鏈式呼叫
    public Food(String name) { this.name = name; }

    // 抽象方法:定義契約,強制實作
    public abstract void eat();

    // 具體方法:提供預設行為,子類別可選擇性覆寫
    public void happyFood() {
        System.out.println(name + ":Good! Eat Me!");
    }

    // 普通方法:內部邏輯
    public final String getName() { return name; } // final 防覆寫
}
抽象與具體方法對比
Food 定義抽象 eat() 契約,提供具體 happyFood() 預設行為

2. 子類別實作範例

class Corn extends Food {
    public Corn() { super("玉米"); }

    @Override
    public void eat() {
        System.out.println("剝皮 → 煮熟 → 咬著吃");
    }
}

class Wheat extends Food {
    public Wheat() { super("小麥"); }

    @Override
    public void eat() {
        System.out.println("磨粉 → 和麵 → 蒸烤 → 品嚐");
    }
}

// 使用多型
public class Test {
    public static void main(String[] args) {
        Food[] foods = { new Corn(), new Wheat() };
        for (Food f : foods) {
            f.eat();        // 多型調用各自實作
            f.happyFood();  // 繼承預設行為
        }
    }
}

三、介面 vs 抽象類別:設計抉擇指南

維度介面 (interface)抽象類別 (abstract class)
核心目的定義**行為契約**(能做什麼)提供**骨架實作**(怎麼做的基礎)
方法實作Java 8 前:全抽象
Java 8+:可有 default/static 方法
可混合抽象與具體方法
欄位僅 static final 常數可有實例欄位、靜態欄位、任意修飾符
建構子❌ 無✅ 有(供子類呼叫 super())
繼承關係多重實作 (implements A, B)
多重繼承 (extends A, B)
單一繼承 (extends Base)
存取修飾符方法隱含 public(Java 9+ 可 private)任意修飾符
適用場景跨領域契約(Serializable、Comparable、Runnable)、API 邊界、SPI 擴展點同領域類別共享狀態/邏輯(Template Method 模式)、框架基類

四、現代 Java 最佳實踐:介面優先,抽象類輔助

1. Java 8+ 介面預設方法:縮小差距

interface Cup {
    void addWater(int ml);
    void drinkWater(int ml);

    // 預設實作:子介面/實作類可選擇性覆寫
    default void rinse() {
        System.out.println("清水沖洗...");
    }

    // 靜態工具方法
    static Cup createDefault() {
        return new SimpleCup();
    }
}

現在介面也能提供「預設實作」,減少對抽象類別的依賴。

2. 經典組合模式:介面定義類型,抽象類提供基礎實作

// 1. 核心契約
interface Repository {
    T findById(Long id);
    List findAll();
    void save(T entity);
    void delete(T entity);
}

// 2. 共享骨架:連線管理、事務模板、通用查詢邏輯
abstract class AbstractJdbcRepository implements Repository {
    protected DataSource dataSource;

    public AbstractJdbcRepository(DataSource ds) { this.dataSource = ds; }

    // 模板方法:具體流程
    public final void save(T entity) {
        try (Connection c = dataSource.getConnection()) {
            c.setAutoCommit(false);
            doSave(c, entity); // 抽象:子類實作具體 SQL
            c.commit();
        } catch (SQLException e) { throw new RepositoryException(e); }
    }

    protected abstract void doSave(Connection c, T entity) throws SQLException;
    // 其他模板方法...
}

// 3. 具體實作
class UserRepository extends AbstractJdbcRepository {
    public UserRepository(DataSource ds) { super(ds); }

    @Override protected void doSave(Connection c, User u) throws SQLException {
        // 實際 INSERT/UPDATE SQL
    }
    // 實作其他抽象方法...
}

五、總結

  • 介面是**類型契約**,支援多重實作與多重繼承,定義「能做什麼」。
  • 抽象類別是**實作骨架**,提供共享欄位、建構子、預設邏輯與模板方法,定義「怎麼做的基礎」。
  • 介面優先:公開 API、跨模組契約、SPI 擴展點**首選介面**。
  • 抽象類輔助:同體系內共享狀態與邏輯、Template Method 模式、**框架基類**用抽象類。
  • Java 8+ default/static 方法讓介面更強大,但**狀態共享仍需抽象類**。
  • 實作類別同時 extends AbstractBase implements InterfaceA, InterfaceB 享受兩全其美。

設計原則:「程式對介面,不對實作」。介面是系統的**邊界與契約**;抽象類是**內部復用的工具**。良好的架構,介面在外圍,抽象類在核心。

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