GenericClass <t extend =“ =” someclass =“”>其中SomeClass的子类应表现不同,仅作为SomeClass

时间:2018-06-22 08:53:27

标签: java generics inheritance interface

我有一些彼此相关的问题。

第一个问题,我有一个接口:

public interface Copiable<T extends Copiable<T>> 
{
    T getCopy();
}

我用来创建实现类的深层副本/克隆。

我有一行类,另一个类用于包含它们,可以说一行类以该类开头:

public class Animal implements Copiable<Animal>

并具有另一个扩展它的类:

public class Dog extends Animal

从理论上(以及我在实践中测试的结果)(动物对象).getCopy()应该返回动物对象,而(狗对象).getCopy()应该返回狗对象。

容器类也是通用的,我希望它只包含一个Animal或其子类,因为我正在使用Animal(和Copiable)方法。所以,我有:

public class Container<T extends Animal>

,在Container的一种方法中,我有类似的东西:

public void doSomething(List<? extends T> list)
{
    // ...
    T temp = list.get(i).getCopy(); // Gives an error (1)
    List<T> newList = new ArrayList<T>();
    newList.add(list.get(i).getCopy()); // Gives an error (2)
}

(1)“错误:类型不兼容:动物无法转换为T”

(2)“错误:找不到适用于add(Animal)的合适方法”

第二个问题是我正在另一个类中使用Container类,例如:

public class Zoo
{
    Container<Animal> animals;
    // ...
    void setAnimals(Container<? extends Animal> animals)
    {
        this.animals = animals; // Gives an error (3)
    }
}

(3)“错误:类型不兼容:容器无法转换为容器”

并且我有Zoo的子类,需要包含Animals的子类:

public class PettingZoo extends Zoo
{
    // Using the same container in the parent class
    // Container<Animal> animals
    // It needs to contain Dogs
    // and I need to be able to set Container<Dog> to animals
    // and use animals as a list of Dogs in this class
}

我想学习什么是处理上述评论中所述情况的好方法。

我愿意更改我的设计,我想了解这种现象的原因以及解决方法。

1 个答案:

答案 0 :(得分:0)

首先,您可能不想使用<T extends Copiable<T>>,因为它实际上并没有增加任何价值:

public interface Copiable<T>{
    T getCopy();
}

第二,您必须向T添加通用参数Animal

public class Animal<T extends Animal<T>> implements Copiable<T>{ ... }

这样,您可以如下定义Dog

public class Dog extends Animal<Dog>{ ... }

您的Container如下:

public class Container<T extends Animal<T>> { ... }

最后,您必须像这样定义Zoo

public class Zoo<T extends Animal<T>> { 
    Container<T> animals;

    ...
}

哪些允许您只为狗创建PettingZoo

public class PettingZoo extends Zoo<Dog> { ... }