重复使用前面的例子,想象一下动物园,动物园管理员必须“处理”新到达的动物(考虑将它们检入动物园)。每只动物的登记过程取决于其类别分类(哺乳动物,鸟类等)。
由于分类学之间的根本区别,这些过程不同 - 例如,鸟类有翅膀,哺乳动物有牙齿。您可能还有一些过程的共享位对于所有动物都是如此,但我在这里省略了它们。
以下是代码:
Animal.java
public interface Animal {
public AnimalProcessor<? extends Animal> getAnimalProcessor();
}
Mammal.java
public abstract class Mammal implements Animal {
@Override
public AnimalProcessor<Mammal> getAnimalProcessor() {
return new MammalProcessor();
}
// Specific to mammals
public abstract int getToothCount();
}
Bird.java
public abstract class Bird implements Animal {
@Override
public AnimalProcessor<Bird> getAnimalProcessor() {
return new BirdProcessor();
}
// Specific to birds
public abstract float getWingspan();
}
AnimalProcessor.java
public interface AnimalProcessor<T extends Animal> {
public void process(T critter);
}
MammalProcessor.java
public class MammalProcessor implements AnimalProcessor<Mammal> {
@Override
public void process(Mammal a) {
System.out.println("Tooth count is " + a.getToothCount());
}
}
BirdProcessor.java
public class BirdProcessor implements AnimalProcessor<Bird> {
@Override
public void process(Bird a) {
System.out.print("Wingspan is " + a.getWingspan());
}
}
Badger.java
public class Badger extends Mammal {
@Override
public int getToothCount() {
return 40;
}
}
Condor.java
public class Condor extends Bird {
@Override
public float getWingspan() {
return 2.9f;
}
}
ZooKeeper.java
import java.util.List;
public class ZooKeeper {
public void processNewAnimals(List<Animal> newcomers)
{
for(Animal critter : newcomers)
{
AnimalProcessor<? extends Animal> ap = critter.getAnimalProcessor();
// This line has a compilation error!
ap.process(critter);
}
}
}
MainClass.java
import java.util.LinkedList;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
ZooKeeper keeper = new ZooKeeper();
List<Animal> animals = new LinkedList<Animal>();
animals.add(new Badger());
animals.add(new Condor());
keeper.processNewAnimals(animals);
}
}
任何地方都没有警告,但 ap.process(critter)无法编译。
我知道这是因为AnimalProcessor<Bird>
不类型为AnimalProcessor<Animal>
,但我看不出如何解决问题。对<T extends Animal>
getAnimalProcessor()
的调用将返回合适的AnimalProcessor<T extends Animal>
,但我无法在代码中表达此内容。
也许我不应该首先将AnimalProcessor拉出来?
当然,目标是能够在不更改核心的情况下添加Reptile
。
答案 0 :(得分:5)
public interface Animal<THIS extends Animal<THIS>> {
AnimalProcessor<THIS> getAnimalProcessor();
}
public abstract class Mammal implements Animal<Mammal> {
有点像Enum<E extends Enum<E>>
。
删除该方法可能是个更好的主意。
答案 1 :(得分:2)
AnimalProcessor.java:
public interface AnimalProcessor<T extends Animal> {
public void process(Animal critter);
}
MammalProcessor.java
public class MammalProcessor implements AnimalProcessor<Mammal> {
@Override
public void process(Animal a) {
System.out.println("Tooth count is " + ((Mammal)a).getToothCount());
}
}