универсальный контейнер универсального класса в Java - PullRequest
0 голосов
/ 23 января 2019

Что я должен написать для "себя" в Java?То, что я хочу, чтобы «я» имел в виду здесь, это «какой бы класс ни представлял конкретную реализацию Vehicle».Это возможно в Java?

import java.util.ArrayList;
import java.util.List;

abstract class Vehicle {
    private Garage<self> garage;

    void setGarage(Garage<self> g) {
        this.garage = g;
        g.vehicles.add(this);
    }
}

class Car extends Vehicle {
}

class Garage<T extends Vehicle> {
    List<T> vehicles = new ArrayList<>();

    void addVehicle(T t) {
        vehicles.add(t);
    }
}

public class GenericFoo {
    public static void main(String[] args) {
        Garage<Car> carGarage = new Garage<>();

        Car c = new Car();
        carGarage.addVehicle(c);
        c.setGarage(carGarage);
    }
}

1 Ответ

0 голосов
/ 24 января 2019

Можно создать что-то эквивалентное, но требует дополнительных усилий.Посмотрите на код ниже:

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.

Надеюсь, это решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...