我有一个新手问题.
interface Animal {
void partner(Animal other);
}
class Lion implements Animal {
int areaUnderControl;
@Override
public void partner(Animal other) {
Lion lion = (Lion) other;
this.areaUnderControl += lion.areaUnderControl;
}
}
class Human implements Animal {
int money;
@Override
public void partner(Animal other) {
Human human = (Human) other;
this.money += human.money;
}
}
Run Code Online (Sandbox Code Playgroud)
我希望具体实现中的伙伴方法只接收其类型或其子类型的参数.一种解决方案是使用泛型将Animal定义为:
interface Animal<T extends Animal<T>> {
void partner(T other);
}
class Lion implements Animal<Lion> {
int areaUnderControl;
@Override
public void partner(Lion other) {
this.areaUnderControl += other.areaUnderControl;
}
}
class Human implements Animal<Human> {
int money;
@Override
public void partner(Human other) {
this.money += other.money;
}
}
Run Code Online (Sandbox Code Playgroud)
但是有人仍然可以滥用这个
class Bear implements Animal<Lion> {
int honey;
@Override
public void partner(Lion other) {
this.honey += other.areaUnderControl; //Problem
}
}
Run Code Online (Sandbox Code Playgroud)
Bear正渴望与Lion合作.有什么方法,我可以把它绑的类型和亚型这
我尝试搜索现有的问题,不知怎的,我觉得界面本身的设计可能有缺陷.如果有人能够指出为什么这是错误的或正确的方法来实现这一目标,我们将不胜感激.
谢谢!
无法在接口级别强制执行此操作,因为从类型安全的角度来看没有理由这样做。那么如果可以定义 aclass Bear implements Animal<Lion>呢?就其本身而言,它是类型安全的(即不会抛出意外的 ClassCastException 等)——这就是泛型的全部意义所在。
事实上,从类型安全的角度来看,很可能您只需要interface Animal<T>(类似于interface Comparable<T>)。是的,这将允许某人定义奇怪的类,这些类使用完全不相关的类的类型参数来实现 Animal。所以呢?这本身并没有什么问题。
在使用此接口的地方,他们可以强制执行您想要的关系,例如public <T extends Animal<? super T>> void someMethodThatUsesAnimal(T animal). 因为只有在使用它的地方才真正关心该partner方法是否将自身作为参数。这类似于如何Comparable使用(例如public <T extends Comparable<? super T>> void sort(List<T> list))