递归通用流利接口 - java

tl;博士

尝试实现层次结构流畅的接口,以便我可以结合节点子类,同时也可以使类独立,但是获取类型参数不在其绑定错误之内。

详细信息

我正在尝试找到一种解决方案,以便可以创建一些类似的内容:

farm
    .animal()
        .cat()
            .meow()
            .findsHuman()
                .saysHello()
                .done()
            .done()
        .dog()
            .bark()
            .chacesCar()
            .findsHuman()
                .saysHello()
                .done()
            .done()
        .done()
    .human()
        .saysHello()
        .done();

同时还能够:

Human human = new Human()
    .saysHello()

我已经接近使用各种策略,但是还没有获得所描述的灵活性。

我目前的尝试使用以下类:

abstract class Base<T extends Base<T>>{

    private T parent;

    Base(){

    }

    Base( T parent ){
        this.parent = parent;
    }

    public T done() throws NullPointerException{
        if ( parent != null ){
            return (T) parent;
        }

        throw new NullPointerException();
    }   
}

class Farm<T extends Base<T>> extends Base{

    private Animal<Farm<T>> animal;
    private Human<Farm<T>> human;

    public Farm(){
        super();
        this.animal = new Animal( this );
        this.human = new Human( this );
    }

    public Animal<Farm> animal(){
        return this.animal;
    }

    public Human<Farm<T>> human(){
        return this.human;
    }
}

class Animal <T extends Base<T>> extends Base{

    private Cat<Animal<T>> cat;
    private Dog<Animal<T>> dog;

    public Animal(){
        super();
        init();
    }

    public Animal( T parent ){
        super( parent );
        init();
    }

    private void init(){
        this.cat = new Cat(this);
        this.dog = new Dog(this);
    }

    public Cat<Animal<T>> cat(){
        return cat;
    }

    public Dog<Animal<T>> dog(){
        return dog;
    }
}

class Human<T extends Base<T>> extends Base{

    public Human<T> saysHello(){
        System.out.println("human says hi");
        return this;
    }
}

class Cat <T extends Base<T>> extends Base{

    private Human<Cat> human;

    public Cat(){
        super();
        init();
    }

    public Cat( T parent ){
        super( parent );
        init();
    }

    private void init(){
        this.human = new Human();
    }

    public Cat<T> meow(){
        System.out.println("cat says meow");
        return this;
    }

    public Human<Cat<T>> findsHuman(){
        return this.human;
    }
}


class Dog <T extends Base<T>> extends Base{

    private Human<Dog> human;

    public Dog(){
        super();
        init();
    }

    public Dog( T parent ){
        super( parent );
        init();
    }

    private void init(){
        this.human = new Human();
    }


    public Dog<T> bark(){
        System.out.println("dog says woof");
        return this;
    }

    public Dog<T> chacesCar(){
        System.out.println("cat drinks milk");
        return this;
    }

    public Human<Dog<T>> findsHuman(){
        return this.human;
    }

}

我看到的错误通常是:

Animal.java:4:类型参数Animal不在其绑定的私有Cat cat中;
Animal.java:5:类型参数Animal不在其绑定的专用Dog dog中;

适用于所有类似的参考文献,也适用于我的示例所需案例:

找不到标志
符号:方法dog()
位置:类Base.dog()

我尝试使用以下解决方案来解决类似问题,但无济于事,因此欢迎任何支持。

参考文献

  • Is there a way to refer to the current type with a type variable?
  • http://vyazelenko.com/2012/03/02/recursive-generics-to-the-rescue/
  • 参考方案

    下面的代码似乎可以正常工作,不需要任何@SuppressWarnings。要掌握的关键概念是T参数实际上是对象的父级的类,但是T的父级可以是任何东西。因此,您需要T extends Base<T>而不是T extends Base<?>

    输出为:

    cat says meow
    human says hi
    dog says woof
    cat drinks milk
    human says hi
    human says hi
    

    ...我认为这是正确的,尽管您可能想更改Dog.chacesCar()方法,以便它不输出cat drinks milk!另外,它应该是chases而不是chaces

    希望这可以帮助!

    abstract class Base<T extends Base<?>> {
    
        private final T parent;
    
        Base() {
            this.parent = null;
        }
    
        Base(T parent) {
            this.parent = parent;
        }
    
        public T done() throws NullPointerException {
            if (parent != null) {
                return parent;
            }
    
            throw new NullPointerException();
        }
    }
    
    class Farm<T extends Base<?>> extends Base<T> {
    
        private final Animal<Farm<T>> animal;
        private final Human<Farm<T>> human;
    
        public Farm() {
            super();
            this.animal = new Animal<>(this);
            this.human = new Human<>(this);
        }
    
        public Animal<Farm<T>> animal() {
            return this.animal;
        }
    
        public Human<Farm<T>> human() {
            return this.human;
        }
    }
    
    class Animal<T extends Base<?>> extends Base<T> {
    
        private Cat<Animal<T>> cat;
        private Dog<Animal<T>> dog;
    
        public Animal() {
            super();
            init();
        }
    
        public Animal(T parent) {
            super(parent);
            init();
        }
    
        private void init() {
            this.cat = new Cat<>(this);
            this.dog = new Dog<>(this);
        }
    
        public Cat<Animal<T>> cat() {
            return cat;
        }
    
        public Dog<Animal<T>> dog() {
            return dog;
        }
    }
    
    class Human<T extends Base<?>> extends Base<T> {
        public Human() {
            super();
        }
    
        public Human(T parent) {
            super(parent);
        }
    
        public Human<T> saysHello() {
            System.out.println("human says hi");
            return this;
        }
    }
    
    class Cat<T extends Base<?>> extends Base<T> {
    
        private Human<Cat<T>> human;
    
        public Cat() {
            super();
            init();
        }
    
        public Cat(T parent) {
            super(parent);
            init();
        }
    
        private void init() {
            this.human = new Human<>(this);
        }
    
        public Cat<T> meow() {
            System.out.println("cat says meow");
            return this;
        }
    
        public Human<Cat<T>> findsHuman() {
            return this.human;
        }
    }
    
    class Dog<T extends Base<?>> extends Base<T> {
    
        private Human<Dog<T>> human;
    
        public Dog() {
            super();
            init();
        }
    
        public Dog(T parent) {
            super(parent);
            init();
        }
    
        private void init() {
            this.human = new Human<>(this);
        }
    
        public Dog<T> bark() {
            System.out.println("dog says woof");
            return this;
        }
    
        public Dog<T> chacesCar() {
            System.out.println("cat drinks milk");
            return this;
        }
    
        public Human<Dog<T>> findsHuman() {
            return this.human;
        }
    
    }
    

    测试代码:

    public static void main(String[] args) {
        Farm<?> farm = new Farm<>();
        farm
            .animal()
                .cat()
                    .meow()
                    .findsHuman()
                        .saysHello()
                        .done()
                    .done()
                .dog()
                    .bark()
                    .chacesCar()
                    .findsHuman()
                        .saysHello()
                        .done()
                    .done()
                .done()
            .human()
                .saysHello()
                .done();
    
        Human human = new Human()
                .saysHello();
    }
    

    Java中的<<或>>>是什么意思? - java

    This question already has answers here: Closed 7 years ago. Possible Duplicate: What does >> and >>> mean in Java?我在一些Java代码中遇到了一些陌生的符号,尽管代码可以正确编译和运行,但对于括号在此代码中的作用却感…

    菱形运算符<>是否等于<?> - java

    我在util.TreeSet类中发现,其中一个构造函数正在使用具有空泛型类型的新TreeMap调用另一个构造函数。 public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } new TreeMap<>是什么意思…

    休眠映射<键,设置<值>> - java

    我有以下表格:@Entity @Table(name = "events") Event --id --name @Entity @Table(name = "state") State --id --name @Entity @Table(name = "action") Action --id …

    无法从ArrayList <String>转换为List <Comparable> - java

    当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…

    合并List <T>和List <Optional <T >> - java

    鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…