重複使用前面的例子,想象一個動物園,新到達的動物必須由Zookeeper「處理」(想想將它們檢入動物園)。每隻動物的檢查過程取決於其類別分類(哺乳動物,鳥類等)。泛型的正確用法是什麼解決了這個編譯錯誤?
由於分類系統的基本差異,這些過程有所不同 - 例如,鳥類有翅膀,哺乳動物有牙齒。你可能也有一些過程的共同點,對所有的動物都是如此,但我在這裏忽略了它們。
下面是代碼:
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(牛馬)不能編譯。 我知道這是因爲AnimalProcessor<Bird>
是而不是類型AnimalProcessor<Animal>
但我看不出如何解決問題。撥打電話<T extends Animal>
getAnimalProcessor()
將返回一個合適的AnimalProcessor<T extends Animal>
,但我不能在代碼中表達這一點。
也許我不應該把動物處理程序放在第一位?
當然,目標是能夠在不更改核心的情況下添加Reptile
。
爲什麼動物的接口,而不是一個抽象類?一個接口應該是某種共享行爲。 – carmenism
我接受你的觀點,並且在我的代碼中改變了它 - 但編譯錯誤仍然存在。 – pjm56