使用通配符和泛型:完成父子类关系的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编写)

相关文章
相关标签/搜索