2011-01-15 3 views
6

Я имею следующую структуру класса:Java - Возвращает правильный тип из родового метода

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); 

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

+1

«Если я сделаю что-то вроде следующего» ... тогда (с какой проблемой вы сталкиваетесь)? –

+0

похоже, что Event должен быть интерфейсом –

ответ

1

Измените подпись 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

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

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