繁体   English   中英

方法链接:如何在多级继承的情况下使用getThis()技巧

[英]Method Chaining: How to use getThis() trick in case of multi level 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<T>>
class DogBuilder<T extends DogBuilder<T>> extends PetBuilder<DogBuilder<T>>
class DogType1Builder extends DogBuilder<DogType1Builder>

现在这会产生两个问题

'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<DogBuilder> builder=new DogBuilder(); //passing <DogBuilder> type ...real pain

有没有更好的办法?

你的问题的根源是一个类设计问题: 你试图从一个具体的类继承 ,这几乎总是一个错误,并且(你的例子)必然会导致许多问题。 要坚持参考线程中给出的例子,你不应该实例化Dog ,因为在这样的宇宙中,一般不存在Dog ,只有Pet s - 只有PoodleNewFoundlandSpaniel等。 , 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();
  }
}

我不相信你可以使用getThis技巧进行多级继承。 你有超级班, Pet<T extends Pet<T>> ,第一个子类, Dog extends Pet<Dog> ,第二个子类Poodle extends Dog 使用getThis技巧,您可以使用protected T getThis()方法和public T rollOver()等方法。 这意味着PoodleDog都有方法protected Dog getThis()public Dog rollOver()

我会遵循Michael Myers的建议来使用协变返回类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM