har*_*bvp 6 java generics inheritance method-chaining
我的问题是在方法链接+继承的背景下不能很好地发挥作用?.但不幸的是,方法链的所有示例/答案都使用单级继承.我的用例涉及多级继承,例如
abstract class PetBuilder{...}
class DogBuilder extends PetBuilder{..}
class DogType1Builder extends DogBuilder {...}
Run Code Online (Sandbox Code Playgroud)
要构造一个Dog Object,我将使用DogBuilder或DogType1Builder
如何使用getThis技巧用于上述用例?
我想使用构建器模式来构造一个复杂的Dog对象(Dog Object Model)".DogType1将有一些添加的属性.
所以使用getThis Trick声明上面的类就会变得像
abstract class PetBuilder<T extends PetBuilder<T>>
class DogBuilder<T extends DogBuilder<T>> extends PetBuilder<DogBuilder<T>>
class DogType1Builder extends DogBuilder<DogType1Builder>
Run Code Online (Sandbox Code Playgroud)
现在这会产生两个问题
'DogBuilder'中的1.builder方法看起来像
public T someMethodInDog(String dogName) {
..
return (T)this; ///i dont want type casting and i cant use getThis Trick Here (compiler reports error for conversion from DogBuilder to T)
}
Run Code Online (Sandbox Code Playgroud)
2.由于DogBuilder已经参数化,因此要创建"DogBuilder"的实例,我将不得不使用
DogBuilder<DogBuilder> builder=new DogBuilder(); //passing <DogBuilder> type ...real pain
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
你的问题的根源是一个类设计问题:你试图从一个具体的类继承,这几乎总是一个错误,并且(你的例子)必然会导致许多问题.要坚持在引用线程中给出的示例,你不应该实例化Dog,因为在这样的宇宙Dog中,一般不存在s,Pet只有Poodles - s,NewFoundlands,Spaniels等.因此,getThis不应该在中级(抽象)类,仅在(具体)叶类中.在所有中级抽象类中,您应该只引用泛型类型参数T,而不是实际的类名.
以下是根据上述规则重写的引用线程的答案中的示例:
public class TestClass {
static abstract class Pet <T extends Pet<T>> {
private String name;
protected abstract T getThis();
public T setName(String name) {
this.name = name;
return getThis(); }
}
static class Cat extends Pet<Cat> {
@Override protected Cat getThis() { return this; }
public Cat catchMice() {
System.out.println("I caught a mouse!");
return getThis();
}
}
// Dog is abstract - only concrete dog breeds can be instantiated
static abstract class Dog<T extends Dog<T>> extends Pet<T> {
// getThis is not implemented here - only in concrete subclasses
// Return the concrete dog breed, not Dog in general
public T catchFrisbee() {
System.out.println("I caught a frisbee!");
return getThis();
}
}
static class Poodle extends Dog<Poodle> {
@Override protected Poodle getThis() { return this; }
public Poodle sleep() {
System.out.println("I am sleeping!");
return getThis();
}
}
static class NewFoundland extends Dog<NewFoundland> {
@Override protected NewFoundland getThis() { return this; }
public NewFoundland swim() {
System.out.println("I am swimming!");
return getThis();
}
}
public static void main(String[] args) {
Cat c = new Cat();
c.setName("Morris").catchMice();
Poodle d = new Poodle();
d.setName("Snoopy").catchFrisbee().sleep();
NewFoundland f = new NewFoundland();
f.setName("Snoopy").swim().catchFrisbee();
}
}
Run Code Online (Sandbox Code Playgroud)
我不相信你可以使用这个getThis技巧来实现多层次的继承。您有超类 、Pet<T extends Pet<T>>第一个子类Dog extends Pet<Dog>和第二个子类Poodle extends Dog。有了getThis窍门,你就有了类似的方法protected T getThis()和方法public T rollOver()。这意味着 和Poodle都有Dog方法protected Dog getThis()和public Dog rollOver()。
我会遵循Michael Myers 的建议,使用协变返回类型。
| 归档时间: |
|
| 查看次数: |
2322 次 |
| 最近记录: |