java方法链接+继承不能很好地结合在一起?
This question has been asked in a C++ context但我对Java很好奇。关于虚拟方法的担忧并不适用(我认为),但如果您遇到这种情况:
abstract class Pet
{
private String name;
public Pet setName(String name) { this.name = name; return this; }
}
class Cat extends Pet
{
public Cat catchMice() {
System.out.println("I caught a mouse!");
return this;
}
}
class Dog extends Pet
{
public Dog catchFrisbee() {
System.out.println("I caught a frisbee!");
return this;
}
}
class Bird extends Pet
{
public Bird layEgg() {
...
return this;
}
}
{
Cat c = new Cat();
c.setName("Morris").catchMice(); // error! setName returns Pet, not Cat
Dog d = new Dog();
d.setName("Snoopy").catchFrisbee(); // error! setName returns Pet, not Dog
Bird b = new Bird();
b.setName("Tweety").layEgg(); // error! setName returns Pet, not Bird
}
在这种类层次结构中,有没有任何方法可以返回this
而不会(有效地)向上转换对象类型
# 1 楼答案
这个老把戏怎么样:
# 2 楼答案
这有点复杂,但你可以用泛型来实现:
# 3 楼答案
不,不是真的。您可以通过使用协变返回类型来解决此问题(感谢McDowell提供了正确的名称):
(如果您担心的话,协变返回类型仅在Java5及更高版本中存在。)
# 4 楼答案
如果您希望避免编译器中未经检查的强制转换警告(并且不希望@SuppressWarnings(“unchecked”)),则需要执行更多操作:
首先,您对Pet的定义必须是自引用的,因为Pet始终是泛型类型:
其次,setName中的
(T) this
强制转换也未选中。为了避免这种情况,请在优秀的Generics FAQ by Angelika Langer中使用“getThis”技术:这将产生下面的代码,该代码在编译和运行时不会出现警告。如果您想扩展子类,那么该技术仍然适用(尽管您可能需要泛化您的中间类)
生成的代码是:
# 5 楼答案
及
}