【问题标题】:Parameter extending appropriate parameter in Java在 Java 中扩展适当参数的参数
【发布时间】:2015-10-23 00:23:48
【问题描述】:

假设我有类Animal 和类Bear 扩展类Animal。 现在在构造函数中我有Animal的参数:

public class Forest {

   private List<Animal> animals;

   public Forest(List<Animal> list) {
      animals = list;
   }
}

为什么我不能这样做?

List<Bear> bears = new ArrayList<>();
new Forest(bears);

我认为BearAnimal 的详细情况。 我只能通过将模板添加到 Forest&lt;P extends Animal&gt; 来解决此问题吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    您可以使用通配符

      private List<? extends Animal> animals;
    
       public Forest(List<? extends Animal> list) {
          animals = list;
       }
    

    这让列表可以包含任何种类的动物,甚至是不同种类的混合。

    这将全部编译:

           List<Bear> bears = new ArrayList<>();
           new Forest(bears);
    
           ...
    
           List<Animal> mix = new ArrayList<>();
           mix.add(new Animal());
           mix.add(new Bear());
    
           new Forest(mix);
    

    缺点是除了它们是动物之外你不会知道类型。

    对于是否以及何时可以使用通配符以及何时使用extendssuper 有一些规则,具体取决于您是否从集合中添加新元素。

    请参阅 Explanation of the get-put principle,有时称为 PECS,代表“Put Extends, Create Super”

    编辑

    为了以后能够将其他动物添加到列表中,您必须将动物列表字段更改为不使用通配符。但是,构造函数仍然可以使用通配符,但您可能应该创建一个新的 List 对象,从构造函数传入列表。

    这将起作用:

    private List<Animal> animals;
    
       public Forest(Collection<? extends Animal> list) {
          animals = new ArrayList<>(list);
       }
    
    
       public void add(Animal a){
           animals.add(a);
       }
    
       public void addAll(Collection<? extends Animal> as){
           animals.addAll(as);
       }
    

    后来

     List<Bear> bears = new ArrayList<>();
     Forest forest = new Forest(bears);
    
     forest.add(new Animal());
    

    我还添加了一个addAll 方法,它也使用通配符

     //same mix and bears lists from before
     Forest forest2 = new Forest(mix);
     forest2.addAll(bears);
    

    【讨论】:

    • 很好的答案 :) 一个问题,在您初始化new Forest(bear) 的那一刻,您可以在这片森林中添加其他种类的动物吗??
    【解决方案2】:

    你也可以用这个方法

    public static <C,T extends C> List<C> convert(List<T> list) {
            List<C> c = new ArrayList<>(list.size());
            c.addAll(list);
            return c;
    }
    
    new Forest(convert(bears));
    

    【讨论】:

      猜你喜欢
      • 2012-03-07
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多