具有泛型的类,将其自身引用为Java中

时间:2017-08-17 13:04:01

标签: java

我有几个类是Animal的子类,它本身就是Lifeform的子类。所有这些类都有一个孩子,它总是属于它自己的类型,因此是通用的。以下简化代码:

public class Animal<T extends Animal> extends Lifeform {
    T child;

    private void initiate() {
        setChild(Animal.class);
    }

    public void setChild(Class<T> animalType) {
        T foundChild = findChild(animalType);
        foundChild.setParent(this);
        this.child = foundChild;
    }
}

其中findChild是一个继承的方法:

public abstract class Lifeform {
    private <L extends Lifeform> L findChild(Class<L> lifeformType) {
        /* Do some stuff with lifeformType to find child */
        ...
        return child;
    }
}

请注意,即使用于标识子项的方法位于Lifeform类中,大多数Lifeforms也不会有子项。

我遇到编译错误,我尝试在Animal.initiate()中调用setChild(Animal.class)。

  

不兼容的类型:java.lang.Class&lt; Animal&gt;无法转换为java.lang.Class&lt; T&gt;

T扩展了Animal,为什么我不能在这里使用Animal.class作为参数?

最初我创建了没有任何参数的setChild,并试图做

findChild(T.class)

然而我意识到我无法从类似的泛型中获取类,并发现一个常见的解决方案是将类添加为参数,这就是我现在所拥有的结果。

如果我尝试在子类中使用setChild,我没有问题:

public class Bat extends Animal<Bat> {
    private void fly() {
        setChild(Bat.class);
        child.fly();
    }
}

不幸的是,在某些情况下,我实际上需要一个没有子类型的动物实例,因此我希望能够将Animal与动物类型化。

我意识到我可以为Animal创建一个额外的子类,而是有一个包含setChild方法的抽象类AnimalAbstract。然而,这意味着我必须根据它们的使用方式将方法与Animal分开。

还有其他方法可以让这项工作吗?

1 个答案:

答案 0 :(得分:1)

在我看来,处理这个问题的一种方法是保留对孩子班级的引用:

if (checkedNodes.ContainsKey(e.Node.Path))

Bat类将成为:

public class Animal<T extends Animal> extends Lifeform {
    protected final Class<T> childClass;
    T child;

    public Animal(Class<T> childClass) {
        this.childClass = childClass;
    }

    protected void initiate() {
        setChild(childClass);
    }

    public void setChild(Class<T> animalType) {
        T foundChild = findChild(animalType);
        foundChild.setParent(this);
        this.child = foundChild;
    }
}