如何让父抽象类Setter返回子类实例?实现链式调用
用泛型解决父类Setter返回类型限制导致的子类链式调用问题
完全可以用泛型实现,不用每个子类都重写父类的Setter方法,下面是具体的改造方案:
改造父类,引入自限定泛型
给抽象父类添加一个自限定泛型参数,让Setter方法返回这个泛型类型,而非父类自身类型。
修改BaseEntity
@MappedSuperclass public abstract class BaseEntity<Self extends BaseEntity<Self>> implements Serializable { private Integer id; public Integer getId() { return id; } @SuppressWarnings("unchecked") public Self setId(Integer id) { this.id = id; return (Self) this; } }
这里的Self是自限定泛型,要求它必须继承BaseEntity<Self>,确保类型转换的安全性。添加@SuppressWarnings("unchecked")是因为编译器无法直接验证这个强制转换,但我们通过泛型约束保证了this就是Self类型。
修改NamedEntity
同样给NamedEntity添加自限定泛型,并在继承BaseEntity时传递这个泛型参数:
@MappedSuperclass public abstract class NamedEntity<Self extends NamedEntity<Self>> extends BaseEntity<Self> { private String name; public String getName() { return name; } @SuppressWarnings("unchecked") public Self setName(String name) { this.name = name; return (Self) this; } }
这样NamedEntity继承的setId方法也会返回Self类型,而非BaseEntity。
修改Person子类
子类继承时,将泛型参数指定为自身类型Person:
@Entity public class Person extends NamedEntity<Person> { private String address; public String getAddress() { return address; } public Person setAddress(String address) { this.address = address; return this; } }
验证链式调用
现在所有Setter方法都会返回Person类型,链式调用可以正常工作:
public Person build() { Person person = new Person() .setId(1) // 返回Person,而非BaseEntity .setName("name") // 返回Person,而非NamedEntity .setAddress("foo"); // 返回Person return person; }
这种方案的核心是利用自限定泛型让父类的Setter方法返回子类的实际类型,避免了重复重写Setter的冗余工作,同时保持代码的扩展性——后续新增子类时,只需继承对应抽象类并指定自身为泛型参数即可。
内容的提问来源于stack exchange,提问作者Witek
相关产品推荐
相关产品推荐

