使用泛型和通配符均可以讓一個方法所表示的算法邏輯適應多種類型。
Java中具有繼承關係的類A、B(A extends B
)它們的集合List<A>
和List<B>
之間是沒有繼承關係的,
能夠使用泛型或通配符來讓一個方法支持同時接受List<A>
和List<B>
。java
這裏分別定義類Animal、Dog和Cat,很顯然,Dog和Cat是Animal的子類。
它們的簡單定義以下:算法
abstract class Animal { public abstract boolean afraidOf(Animal other); } class Cat extends Animal { @Override public boolean afraidOf(Animal other) { if (other instanceof Dog) { return true; } return false; } } class Dog extends Animal { @Override public boolean afraidOf(Animal other) { if (other instanceof Cat) { return false; } return true; } }
上面Animal類定義了boolean afraidOf(Animal other)
方法,表示一個動物是否懼怕另外一個動物。ide
能夠看到Cat和Dog有着不一樣的表現。code
假設有下面需求:
從一個List<Animal>
中找到某個Animal對象懼怕的全部其它動物。
對應有如下的API方法:對象
public List<Animal> findScaredAnimals(List<Animal> animals, Animal who) { //... }
若是這時有List<Dog>
或者List<Cat>
這種,也應該是支持的。
能夠經過通配符或者泛型方法實現。繼承
使用List<? extends Animal>
這樣的形參,就能夠接收集合項爲Animal子類的任意List。class
public List<Animal> findScaredAnimals(List<? extends Animal> animals, Animal who) { //... }
這時就能夠這樣調用了:泛型
List<Dog> dogs; .... findScaredAnimals(dogs, animal); ...
其餘Animal子類的List都是能夠的。List
拋開實際意義,假設須要findScaredAnimals()中,返回值和參數對應的具體Animal子類型是一致的,那麼就須要用到泛型了:方法
public <T extends Animal> List<T> findScaredAnimals(List<T> animals, T who) { //... }
能夠看到,泛型類型參數T同時約束了多個地方。
泛型參數也能夠是多個的,並且之間存在關係。
以上經過一個不太實際的案例說明了使用泛型和通配符來解決List泛型集合之間的「匹配」問題。這也是它們的主要用途之一。
(本文使用Atom編寫)