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
给出的错误:
类型不匹配:无法从 Animal 转换为 Bear
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
.
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; }
.
这篇关于链接、返回基对象以及与扩展类的类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:链接、返回基对象以及与扩展类的类型不匹配
基础教程推荐
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01