Я задал аналогичный вопрос в другом сообщении (Как реализовать метод из производного класса, который не требует приведения), но это немного более конкретно. Предположим, у меня есть 3 класса: Автомобиль, Автомобиль, Кабриолет. Автомобиль расширяет автомобиль, а кабриолет расширяет автомобиль. Мне нужен метод для каждого класса, который возвращает список, не требующий приведения во время выполнения. Подумав, я считаю, что это невозможно, но я также хочу услышать ваше мнение
public class Vehicle {
public List<? extends Vehicle> getList() {
return new ArrayList<Vehicle>();
}
}
public class Car extends Vehicle {
@Override
public List<? extends Car> getList() {
return new ArrayList<Car>();
}
}
public class Convertible extends Car {
@Override
public List<? extends Convertible> getList() {
return new ArrayList<Convertible>();
}
}
Чтобы не использовать приведение, мне пришлось бы возвращать определенный тип элемента в списке (List<Convertible>
), но тогда, если бы я хотел расширить класс Convertible, я больше не мог бы этого делать.
Есть ли способ обойти эту ситуацию?
2 ответа
Если вы хотите уметь писать
List<Vehicle> list1 = new Vehicle().getList();
List<Car> list2 = new Car().getList();
List<Convertible> list3 = new Convertible().getList();
Вам не повезло. List<Car>
не является подтипом List<Vehicle>
, поэтому возвращаемые типы несовместимы. Вы можете избавиться от предупреждений компилятора, используя свой код, написав, например,
List<Car> list = new ArrayList<Car>(new Car().getList());
Однако я не совсем уверен, почему метод getList()
должен быть унаследован. Если вы всегда знаете тип Vehicle
, для которого вызываете метод, вы также можете иметь отдельный метод в каждом классе, называемый getVehicleList()
, getCarList()
и getConvertibleList()
, возвращает List<Vehicle>
, List<Car>
и List<Convertible>
соответственно.
Ты можешь написать
public class Vehicle<V extends Vehicle> {
public List<V> getList() {
return new ArrayList<V>();
}
}
public class Car<C extends Car> extends Vehicle<C> {
}
public class Convertible extends Car<Covertible> {
}
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
Vehicle
принять аргумент универсального типа, а затем использовать этот аргумент для типа списка?List<? extends Convertible>
как тип переменной, хранящей возвращаемое значение.