super 是 Java 繼承體系中的關鍵字,用於訪問父類成員(欄位、方法、建構子)。在 Android 開發中,Activity、Fragment、View 等核心組件大量使用繼承,熟練掌握 super 用法至關重要。
當子類與父類存在同名欄位或方法時,使用 super.成員 顯式調用父類版本:
class FatherClass {
public int value = 100;
public void f() {
System.out.println("FatherClass.value: " + value);
}
}
class ChildClass extends FatherClass {
public int value = 200; // 遮蔽父類欄位
@Override
public void f() {
super.f(); // 調用父類方法
value = 200; // 子類欄位
System.out.println("ChildClass.value: " + value); // 200
System.out.println("this.value: " + this.value); // 200
System.out.println("super.value: " + super.value); // 100 (父類欄位)
}
}
// 輸出:
// FatherClass.value: 100
// ChildClass.value: 200
// 200
// 100
this.value 和 value 等價,指向子類欄位super.value 穿透遮蔽,直接訪問父類欄位super.method() 可選擇性調用父類邏輯(如擴充而非完全替換)子類建構子必須調用父類建構子,規則如下:
super(參數列表) 顯式調用特定父類建構子super(),編譯器自動插入無參 super()super() 必須是建構子第一條語句class SuperClass {
private int n;
public SuperClass() {
System.out.println("SuperClass() 無參建構子");
}
public SuperClass(int n) {
System.out.println("SuperClass(" + n + ") 帶參建構子");
this.n = n;
}
}
class SubClass extends SuperClass {
private int n;
// 情況 1:無顯式 super() → 自動調用 SuperClass()
public SubClass(int n) {
System.out.println("SubClass(" + n + ")");
this.n = n;
}
// 情況 2:顯式調用帶參父類建構子
public SubClass() {
super(300); // 必須第一行
System.out.println("SubClass() 無參建構子");
}
}
public class Test {
public static void main(String[] args) {
new SubClass(); // 輸出: SuperClass(300) → SubClass()
new SubClass(400); // 輸出: SuperClass() → SubClass(400)
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // 必須第一行,初始化父類狀態
setContentView(R.layout.activity_main);
// 子類初始化邏輯...
}
@Override
public void onStart() {
super.onStart(); // 確保父類生命週期邏輯執行
// 子類邏輯...
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // 繪製背景、預設樣式
// 自定義繪製邏輯...
canvas.drawCircle(centerX, centerY, radius, paint);
}
public class CustomView extends View {
public CustomView(Context context) {
this(context, null); // 委派給下一個建構子
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0); // 委派
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); // 必須調用父類對應建構子
init(attrs);
}
}
| 錯誤模式 | 後果 | 正確做法 |
|---|---|---|
| 建構子中未調用 super() 且父類無無參建構子 | 編譯錯誤 | 顯式調用 super(參數) |
| super() 非建構子第一行 | 編譯錯誤 | 移至第一行 |
| 覆寫方法忘記 super.method() | 父類關鍵邏輯缺失(如狀態初始化、資源釋放) | 評估是否需要調用父類實現,通常 onCreate/onStart/onDraw 等必須調用 |
| 靜態方法使用 super | 編譯錯誤 | 靜態方法屬於類,不屬於實例,無 super 概念 |
Java 8 介面預設方法引入多重繼承場景:
interface A { default void foo() { System.out.println("A"); } }
interface B extends A { default void foo() { System.out.println("B"); } }
interface C extends A { default void foo() { System.out.println("C"); } }
class D implements B, C {
@Override
public void foo() {
B.super.foo(); // 顯式指定調用 B 的實現
C.super.foo(); // 顯式指定調用 C 的實現
}
}