方法链接:如何在多级inheritance的情况下使用getThis()技巧
我的问题是在方法链接+inheritance的背景下不能很好地发挥作用? 。 但不幸的是,方法链的所有示例/答案都使用单级inheritance。 我的用例涉及多级inheritance,例如
abstract class PetBuilder{...} class DogBuilder extends PetBuilder{..} class DogType1Builder extends DogBuilder {...}
要构造一个Dog Object,我将使用DogBuilder或DogType1Builder
如何使用getThis技巧用于上述用例?
我想使用构建器模式来构造一个复杂的Dog对象(Dog Object Model) 。“DogType1将有一些添加的属性。
所以使用getThis Trick声明上面的类会变得像
abstract class PetBuilder<T extends PetBuilder> class DogBuilder<T extends DogBuilder> extends PetBuilder<DogBuilder> class DogType1Builder extends DogBuilder
现在这会产生两个问题
‘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) }
2.由于DogBuilder已经参数化,因此要创建“DogBuilder”的实例,我将不得不使用
DogBuilder builder=new DogBuilder(); //passing type ...real pain
有没有更好的办法?
你的问题的根源是一个类设计问题: 你试图从一个具体的类inheritance ,这几乎总是一个错误,并且(你的例子)必然会导致许多问题。 为了坚持参考线程中给出的例子,你不应该实例化Dog
,因为在这样的宇宙中,一般不存在Dog
,只有Pet
s – 只有Poodle
, NewFoundland
, Spaniel
等。 , getThis
不应该在中级(抽象)类中实现,只能在(具体)叶类中实现。 在所有中级抽象类中,您应该只引用generics类型参数T
,而不是实际的类名。
以下是根据上述规则重写的引用线程的答案中的示例:
public class TestClass { static abstract class Pet > { private String name; protected abstract T getThis(); public T setName(String name) { this.name = name; return getThis(); } } static class Cat extends Pet { @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> extends Pet { // 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 { @Override protected Poodle getThis() { return this; } public Poodle sleep() { System.out.println("I am sleeping!"); return getThis(); } } static class NewFoundland extends Dog { @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(); } }
我不相信你可以使用getThis
技巧进行多级inheritance。 你有超级class, Pet
,第一个子类, Dog extends Pet
,第二个子类Poodle extends Dog
。 使用getThis
技巧,您可以使用protected T getThis()
方法和public T rollOver()
等方法。 这意味着Poodle
和Dog
都有方法protected Dog getThis()
和public Dog rollOver()
。
我会遵循Michael Myers的建议来使用协变返回类型。