使用通配符和泛型:完成父子類關係的List對象的類型匹配

泛型和通配符

使用泛型和通配符均可以讓一個方法所表示的算法邏輯適應多種類型。
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編寫)

相關文章
相關標籤/搜索