假设我有以下内容:
public interface Talk {
void Talks();
}
public interface Walk {
void Walks();
}
public class Dog implements Talk, Walk {
public Dog() {
// ...
}
public void Talks() {
// ...
}
public void Walks() {
// ...
}
}
public class Cat implements Talk, Walk {
public Cat() {
// ...
}
public void Talks() {
// ...
}
public void Walks() {
// ...
}
}
我正试图将Dog类中的一个对象Dog-Dog=new Dog(…(和Cat类中的另一个对象Cat Cat=new Cat(…(添加到同一数组中,但由于它们来自不同的类,因此不能添加到相同的数组中。
所以我的解决方案是创建一个抽象类,将Talk和Walk扩展到该抽象类,并让类Dog和Cat从抽象类继承,这样我就可以创建一个用于放置Dog和Cat对象的抽象类数组。
Abstract abstract = { new Dog(...), new Cat(...) };
还有比这更好的解决方案吗?
接口已经是一个良好的开端。您可以定义一个Walk
或Talk
的数组,但对于组合,您需要另一个将两者组合在一起的接口(以及您的类需要实现的接口(。
您可能还想使用集合而不是数组,例如List<Walk>
等
请注意,我已经更新了我的答案,因为List<? extends Walk & Talk>
实际上是不可能的。您可以使用<T extends Walk & Talk>
和List<T>
,但只有当您为T
使用具体类型(例如List<Dog>
(时,这才会起作用。如果您需要确保元素的实际类型实现这两个接口,例如,如果Turtle
只实现Walk
,则<T extends Walk & Talk
不允许使用Turtle
,那么这将非常有用。
那么为什么List<? extends Walk & Talk>
不可能呢?首先,你不能添加任何内容,因为编译器不知道它是否安全(通配符?
可以匹配List<Dog>
或List<Cat>
,但编译器不知道(。
另一个原因是:list.get(index)
的返回类型是什么?会是Walk
吗?会是Talk
吗?编译器无法决定并需要您。如果你创建了一个接口WalkTalk extends Walk, Talk
,你可以使用它,编译器很高兴:(
Object[] objs = { (Object)(new Dog()), (object)(new Cat(), ... }
// or
List<Object> lobj = new ArrayList<>();
lobj.add((Object) new Dog());
...
Dog dog = (Dog) lobj.get(0);
// or
Cat cat = (Cat)objs[1];