【发布时间】:2018-12-01 17:05:45
【问题描述】:
我有几个彼此相关的问题。
第一个问题,我有一个接口:
public interface Copiable<T extends Copiable<T>>
{
T getCopy();
}
我用来创建实现类的深层副本/克隆。
我有一行类和另一个用于包含它们的类,假设一行类以类开头:
public class Animal implements Copiable<Animal>
并且有另一个类扩展它:
public class Dog extends Animal
理论上(以及我在实践中测试的结果) (Animal object).getCopy() 应该返回一个 Animal 对象, (Dog object).getCopy() 应该返回一个 Dog 对象。
容器类也是通用的,我希望它只包含一个 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)“错误:不兼容的类型:Animal不能转换为T”
(2)“错误:没有找到适合添加(动物)的方法”
第二个问题是我在另一个类中使用 Container 类,比如:
public class Zoo
{
Container<Animal> animals;
// ...
void setAnimals(Container<? extends Animal> animals)
{
this.animals = animals; // Gives an error (3)
}
}
(3)“错误:不兼容的类型:Container无法转换为Container”
我有 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
}
我想了解处理上述 cmets 中所述情况的好方法。
我愿意改变我的设计,我想了解这种行为的原因以及如何解决它。
【问题讨论】:
-
public interface Copiable<T extends Copiable<T>>为什么不能只使用T? -
public class Animal<T extends Animal<T>> implements Copiable<T>{}和public class Dog extends Animal<Dog>{}。这应该可以解决问题 -
<T extends Foo<T>>几乎总是被那些不完全理解泛型的人弄错。 -
Dog扩展Animal的事实意味着Dog实现Copiable<Animal>,而不是Copiable<Dog>。 -
现有的接口
Cloneable具有相同的用途。深克隆与浅克隆是一种实现选择。通过从clone()返回正确的类型,您可以避免出现的大多数泛型内容。
标签: java generics inheritance interface