鏈式調用(Method Chaining)讓代碼流暢如 obj.setA(1).setB(2).setC(3)。但當子類繼承父類且父類方法返回 this(父類類型)時,調用父類方法後會「斷鏈」——無法繼續調用子類特有方法。本文分析原因,給出子類重寫 + super 調用 + 返回 this的標準解法,並溯源 StringBuilder 源碼驗證。
class BaseOption {
private String id, name;
public BaseOption setId(String id) { this.id = id; return this; }
public BaseOption setName(String name) { this.name = name; return this; }
}
class AppearanceOption extends BaseOption {
private String color, shape, size;
// 子類特有方法返回 AppearanceOption
public AppearanceOption setColor(String c) { this.color = c; return this; }
public AppearanceOption setShape(String s) { this.shape = s; return this; }
public AppearanceOption setSize(String s) { this.size = s; return this; }
}
// 使用時
AppearanceOption ao = new AppearanceOption();
ao.setId("1").setColor("red"); // 編譯錯誤!setId 返回 BaseOption,無 setColor 方法
class AppearanceOption extends BaseOption {
// ... 子類字段與方法 ...
@Override
public AppearanceOption setId(String id) {
super.setId(id); // 復用父類邏輯
return this; // 返回子類類型,保持鏈式
}
@Override
public AppearanceOption setName(String name) {
super.setName(name);
return this;
}
}
// 現在完美支持
AppearanceOption ao = new AppearanceOption();
ao.setId("1").setName("test").setColor("red").setShape("circle"); // 編譯通過,鏈式暢通
Java 支持協變返回類型:重寫方法的返回類型可以是父類方法返回類型的子類型。編譯器允許 BaseOption → AppearanceOption 的返回類型收窄,從而實現鏈式類型安全。
// java.lang.AbstractStringBuilder
public AbstractStringBuilder append(String str) { ... return this; }
// java.lang.StringBuilder extends AbstractStringBuilder
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
標準庫正是用此模式:抽象父類定義通用鏈式骨架,具體子類重寫收窄返回類型,兼顧復用與流暢 API。
withX() 返回新實例)。Self 類型參數(F-bounded polymorphism)統一處理。子類重寫父類鏈式方法、調用 super.xxx()、返回 this 是 Java 中保持繼承體系鏈式調用暢通的標準模式。這利用了協變返回類型特性,源碼級驗證於 StringBuilder、StringBuffer 等核心類。設計時需權衡鏈式便利性與繼承複雜度,避免過度設計。