Java - вернуть правильный тип из общего метода - PullRequest
6 голосов
/ 15 января 2011

У меня следующая структура классов:

public class Team {
    ...
}

public class Event {

}

public abstract class Fixture<T extends Team> implements Event {
   ...
}

public abstract class Forecast<Event> {

}

public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{

}

Я пытаюсь смоделировать спортивные события всех видов (например, «Приспособление» предназначено для конкретной игры между двумя участниками, играющими друг против друга, тогда как другойтип «Событие» может иметь много участников), наряду с прогнозами на результат конкретных «Событий».У меня есть универсальный метод:

public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) {

}

Я хочу иметь возможность вернуть экземпляр MyPrediction, который имеет универсальный тип аргумента fixture, но я не могу 'Кажется, я так и делаю.Например, если я сделаю что-то вроде следующего, я получу ошибку компиляции:

SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>();
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch);

Я хочу изменить свою структуру классов, чтобы включить эту функцию.Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 15 января 2011

Изменить сигнатуру getMyPrediction на

public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture)

Это говорит компилятору, что типы фиксаторов в аргументе и результате совпадают, что позволяет проходить проверку типов.

Вот полный пример, с некоторыми другими незначительными изменениями для его компиляции.В нем представлен класс Predictor для хранения метода getMyPrediction и метода doit для демонстрации использования образца:

public interface Team {
}

public interface Event {
}

public abstract class Fixture<T extends Team> implements Event {
}

public abstract class Forecast<T> {
}

public class MyPrediction<T extends Fixture<? extends Team>> extends
        Forecast<Fixture<? extends Team>> {
}

public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> {
}

public class SoccerTeam implements Team {
}

public class EnglishSoccerTeam extends SoccerTeam {
}

public class Predictor {

    public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) {
        return new MyPrediction<T>();
    }

    public void doit() {
        SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>();
        MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch);
    }
}

Как уже отмечалось, вам может потребоваться ввести один или несколько объектов фабрики для выполнениязначимая работа в реализации MyPrediction.

0 голосов
/ 15 января 2011

Система типов Java недостаточно мощна, чтобы напрямую делать то, что вы предлагаете, из-за стирания типов (общие параметры недоступны во время выполнения.

Обычным решением является создание отдельного класса EventFactory, который затем можно передать любому методу, который должен создать конкретный экземпляр подтипа Event.

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