問題:`View.OnClickListener` 接口中 `onClick(View v)` 方法未顯式加 `abstract` 關鍵字,為什麼實現類仍被強制要求實現?這涉及 Java 接口的**隱式抽象**與**默認方法**演進機制。
// android.view.View.OnClickListener (Android SDK)
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v); // ← 無 abstract、無 default、無 static
}
| 版本 | 接口方法默認屬性 | 關鍵字要求 |
|---|---|---|
| Java 7 及之前 | 隱式 public abstract | 允許寫 abstract,但通常省略 |
| Java 8 | 隱式 public abstract,新增 default / static 方法 | 無修飾 = 抽象方法;有 default/static = 具體方法 |
| Java 9+ | 同上,新增 private 方法 | 同 Java 8 |
**結論**:接口中**無修飾符的方法默認就是 `public abstract`**,編譯器會自動補全。寫不寫 `abstract` 對語義無影響,慣例上**省略**以保持簡潔。
// 實現類
public class MyClickListener implements View.OnClickListener {
// ✅ 必須實現,否則編譯錯誤:MyClickListener is not abstract and does not override abstract method onClick(View)
@Override
public void onClick(View v) {
// 業務邏輯
}
}
// 若不想實現,必須宣告為抽象類
public abstract class BaseClickListener implements View.OnClickListener {
// 可選實現,或留給子類
}
| 成員類型 | 聲明範例 | 隱式修飾符 | 說明 |
|---|---|---|---|
| 常量 | `int MAX = 100;` | `public static final` | 必須初始化,不可變 |
| 抽象方法 | `void doIt();` | `public abstract` | Java 8+ 可用 `default` 提供默認實現 |
| 默認方法 | `default void log() {}` | `public` (非 abstract) | 實現類可選擇覆寫 |
| 靜態方法 | `static void helper() {}` | `public static` | 屬於接口,不可覆寫 |
| 私有方法 | `private void internal() {}` | `private` | Java 9+,供默認/靜態方法內部復用 |
// ❌ 誤以為無 abstract 就可以不實現
interface Bad { void doSomething(); } // 實際是 public abstract
// ❌ 誤以為接口方法可以是 protected/package-private
interface Bad2 { protected void x(); } // 編譯錯誤:接口方法只能是 public
// ✅ 正確:Java 8+ 提供默認實現,實現類可不覆寫
interface Good {
void required(); // 必須實現
default void optional() {} // 可選覆寫
}
核心記住:**接口 = 契約**。無修飾方法 = 必須實現的契約條款;`default` 方法 = 附帶的參考實現。`abstract` 關鍵字在接口中純屬歷史殘留,現代 Java 代碼規範(Google Java Style、Alibaba Java Manual)均建議**省略**。