Java继承:将列表限制为子类对象

时间:2017-07-18 13:22:29

标签: java list generics inheritance collections

假设我有3个课程:Car,Convertible和Garage。

汽车:

public class Car {    
    private String name;
    private String color;

    public Car(String name, String color) {
        this.name = name;
        this.color = color;
    }    
    //Getters
}

Convertible继承自Car:

public class Convertible extends Car{
    private boolean roof;

    public Convertible(String name, String color, boolean roof) {
        super(name, color);
        this.roof = roof;
    }

    public boolean isRoof() {
        return roof;
    }
}

Garage存储汽车列表:

public class Garage {
    private int capacity;
    private List<Car> cars = new LinkedList<Car>();

    //Setter for capacity
}

我怎样才能创建一个名为Garage的{​​{1}}子类,只能存储Convertibles?

4 个答案:

答案 0 :(得分:6)

您可以使用一些泛型:

public class Garage<T extends Convertible> {
    private int capacity;
    private List<T> cars = new LinkedList<T>();

    public Garage(int capacity) {
        this.capacity = capacity;
    }
}

这意味着当您实例化Garage时,您现在必须包含一个可转换的子参数类型或其子类。

Garage<Convertible> cGarage = new Garage<>();

答案 1 :(得分:5)

泛型将在这里提供帮助。

Garage类设为通用Garage<T extends Car>,其中T是可以存储的汽车类型。将cars列表重写为通用视图List<T>

然后,Garage<Convertible>将成为您的“ConvertibleGarage”。

答案 2 :(得分:2)

你真的不需要制作第二个Garage类,你可以使用泛型:

public class Garage<T extends Car> {

   private int capacity;

   private List<T> cars;

   public Garage() {
       this.cars = new LinkedList<>();
   }

   public static void main(String[] args) {
       Garage<Convertible> garConv = new Garage<>();
       garConv.cars.add(new Convertible("", "", true));

       Garage<Car> garCar = new Garage<>();
       garCar.cars.add(new Car("", ""));
   }
}

只有这个课程,你可以有车库和敞篷车

答案 3 :(得分:2)

正如其他答案所解释的那样,您可以通过Garage generic 来解决问题,从而允许Garage的任何实例处理完全一种种类的汽车。

但到目前为止缺少的是:这不是解决问题的“选项” - 这只是“走到这里的方式”。您使用继承的想法是“完全错误的”。含义:当人们从面向对象的设计开始时,他们认为继承是一切的答案。实际上那是是真的。您在两个类之间创建extends关系时非常小心。

特别是在谈论容器 - “包含”其他对象的类时 - 首先想到的是泛型