在Java中,泛型引用自身作为泛型类型的类

在Java中,泛型引用自身作为泛型类型的类,java,Java,我有几个类是动物的亚类,动物本身就是生命形式的亚类。所有这些类都有一个子类,它总是属于自己的类型,因此是泛型。简化代码如下: public class Animal<T extends Animal> extends Lifeform { T child; private void initiate() { setChild(Animal.class); } public void setChild(Class<T> a

我有几个类是动物的亚类,动物本身就是生命形式的亚类。所有这些类都有一个子类,它总是属于自己的类型,因此是泛型。简化代码如下:

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;
    }
}
然而,我意识到我无法从这样的泛型中获取类,并发现一个常见的解决方案是将类作为参数添加,这就是我现在所拥有的结果

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

public class Bat extends Animal<Bat> {
    private void fly() {
        setChild(Bat.class);
        child.fly();
    }
}
公共类蝙蝠扩展动物{
私人飞行{
setChild(蝙蝠级);
child.fly();
}
}
不幸的是,在一些情况下,我实际上需要一个没有子类型的动物实例,因此我希望能够将child与animal设置为type

我意识到我可能可以为Animal创建一个额外的子类,取而代之的是一个包含setChild方法的抽象类AnimalStract。然而,这意味着我必须根据使用方法的不同将方法与动物分开


还有其他方法可以解决这个问题吗?

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

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;
    }
}
公共类动物扩展生命形式{
受保护的最终类子类;
T儿童;
公共动物(儿童类){
this.childClass=childClass;
}
受保护的无效初始化(){
setChild(childClass);
}
public void setChild(类animalType){
T foundChild=findChild(animalType);
foundChild.setParent(本文件);
this.child=foundChild;
}
}
然后,Bat类将成为:

public class Bat extends Animal<Bat> {
    public Bat() {
        super(Bat.class);
    }

    private void fly() {
        setChild(Bat.class); // or initiate();
        child.fly();
    }
}
公共类蝙蝠扩展动物{
公共Bat(){
超级(蝙蝠级);
}
私人飞行{
setChild(Bat.class);//或initiate();
child.fly();
}
}

你的
生命形式
界面是什么样子的?@AdamArold它是一个抽象类。我在上面以简化的形式添加了它。
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;
    }
}
public class Bat extends Animal<Bat> {
    public Bat() {
        super(Bat.class);
    }

    private void fly() {
        setChild(Bat.class); // or initiate();
        child.fly();
    }
}