Можно создать что-то эквивалентное, но требует дополнительных усилий.Посмотрите на код ниже:
import java.util.ArrayList;
import java.util.List;
public class GenericsSample {
public static void main(String[] args) {
Garage<Car> carGarage = new Garage<>();
Car c = new Car();
carGarage.addVehicle(c);
c.setGarage(carGarage);
}
abstract static class Vehicle<T extends Vehicle<T>> {
private Garage<T> garage;
void setGarage(Garage<T> g) {
this.garage = g;
g.vehicles.add(self());
}
abstract T self();
}
static class Car extends Vehicle<Car> {
@Override
Car self() {
return this;
}
}
static class Garage<T extends Vehicle<T>> {
List<T> vehicles = new ArrayList<>();
void addVehicle(T t) {
vehicles.add(t);
}
}
}
Что здесь важно:
Vehicle
параметризация класса - фактически, тип T
сам по себе Vehicle
.Нам нужно, чтобы он мог получить фактический тип с родительского уровня.В нашем случае T
представляет Car
(и может фактически представлять любой подкласс).Vehicle<T extends Vehicle<T>>
может показаться немного сложным, но на самом деле это довольно легко понять - T
является «ссылкой» на подкласс из суперкласса. - метод self () - я добавил метод self () в
Vehicle
класс.Обратите внимание, что self()
возвращает T
, а не Vehicle
, что означает, что тип возвращаемого объекта - это конкретный класс реализации.Каждая реализация должна просто возвращать this
.
Надеюсь, это решит вашу проблему.