链接,返回基础对象以及与扩展类的类型不匹配 [英] Chaining, returning base objects, and type mismatch to extended classes
问题描述
我遇到过这样的课程.它具有"with"方法,该方法可以使人们将事物链接在一起.
I have come across a class like this. It holds a "with" method that lets people chain things together.
public class Bear {
protected List<String> names = new ArrayList<String>();
protected List<String> foods = new ArrayList<String>();
public Bear withName(String name) {
names.add(name);
return this;
}
public Bear withFood(String food) {
foods.add(food);
return this;
}
}
// ...somewhere else
Bear b = new Bear().withName("jake").withName("fish");
我发现两个类共享90%的相同代码.因此,我在它们之间创建了一个基类,并将25个左右的"with"方法(包括成员变量和全部)传递给它.
I found two classes that shared 90% of the same code. So, I created a base class between them, and transferred the 25 or so "with" methods to it (with the member variables and all.) Like so:
public abstract class Animal {
protected List<String> names = new ArrayList<String>();
public Animal withName(String name) {
names.add(name);
return this;
}
}
public class Bear extends Animal {
protected List<String> foods = new ArrayList<String>();
public Bear withFood(String food) {
foods.add(food);
return this;
}
}
但是,这现在破坏了一切(并且有很多地方在这两个类的设计中都使用了此功能.
However, this now breaks everything (And there is a lot of places that use this with design for these two classes).
Bear b = new Bear().withName("jake"); // Breaks
bear b2 = new Bear().withFood("fish"); // Fine
给出的错误:
类型不匹配:无法从动物转换为熊
Type mismatch: cannot convert from Animal to Bear
显然,当您返回基类this时,它返回的是Bear类型,并且不执行任何自动转换.
Apparently, when you return the base class this, it's returning a Bear type, and does not do any sort of automatic conversion.
我有什么解决/绕过此问题的选择?
What are my options to solve/bypass this issue?
推荐答案
您正在寻找 CRTP :
public abstract class Animal<T extends Animal<T>> {
protected List<String> names = new ArrayList<String>();
public T withName(String name) {
names.add(name);
return (T)this;
}
}
这将产生不可避免的未经检查的强制转换警告,因为类型系统无法阻止您编写class Cat extends Animal<Dog> {} class Dog extends Animal<Dog>
.
This will give an unavoidable unchecked cast warning, since the type system cannot prevent you from writing class Cat extends Animal<Dog> {} class Dog extends Animal<Dog>
.
如果基类中有多个构建器方法,则可以通过编写private T returnThis() { return (T)this; }
隔离警告.
If you have multiple builder methods in the base class, you can isolate the warning by writing private T returnThis() { return (T)this; }
.
这篇关于链接,返回基础对象以及与扩展类的类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!