Наследование универсального типизированного метода от абстрактного класса — преобразование в определенный тип
-
13-12-2019 - |
Вопрос
(Работаю на Java) У меня есть абстрактный класс с универсальной типизацией по всему классу:
public abstract class ConnectionProcessor<T>
{
public void process()
{
for (List<T> resultsPage : connection)
{
processPage(resultsPage);
}
}
protected abstract void processPage(List<T> resultsPage);
}
У меня есть другой класс, который расширяет указанный абстрактный класс со следующим объявлением:
public class AlbumProcessor<Album> extends ConnectionProcessor
{
@Override
protected void processPage(List resultsPage)
{
//Do stuff here specific to Album
}
}
Это объявление работает нормально, но в processPage
Я хочу сделать Album
- специфические вещи, и я стараюсь избегать кастинга, когда мне это не нужно использовать.Я бы предпочел, чтобы это было объявление метода:
protected void processPage(List<Album> resultsPage)
Но это не соответствует требованиям для переопределения processPage
от ConnectionProcessor
.Почему это происходит?Как я могу добиться желаемого поведения?Я бы подумал, что в AlbumProcessor
Я мог бы просто подключить <Album>
везде ConnectionProcessor
имеет <T>
, но это просто не тот случай.
Решение
Попробуй
//extend prameterized version of ConnectionProcessor<T> with Album as actual type argument
public class AlbumProcessor extends ConnectionProcessor<Album> {
вместо
public class AlbumProcessor<Album> extends ConnectionProcessor {
Когда вы выполняете описанное выше, вы расширяете необработанную версию универсального типа ConnectionProcessor<T>
и вводим новый параметр формального типа - Album
(как T
), который в данном случае не является фактическим аргументом типа.
Другие советы
Это потому, что вы не привязали свой универсальный тип суперкласса T
к Album
.
Скорее, это то, что вам следует сделать:
public class AlbumProcessor extends ConnectionProcessor<Album>
Итак, когда вы переопределите свой метод processPage
, (используя IDE), он сгенерирует код следующим образом:
@Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
public class AlbumProcessor extends ConnectionProcessor<Album>
Попробуй:-
public class AlbumProcessor extends ConnectionProcessor<Album>
{
@Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
}
Вам нужно привязать свой суперкласс к типу, который вы хотите указать в качестве параметра типа для вашего списка в объявлении вашего метода..
Как насчет чего-нибудь более похожего на это?
import java.util.List;
public abstract class ConnectionProcessor<T>
{
public void process()
{
System.out.println("Hello");
}
protected abstract void processPage(List<? extends T> resultsPage);
}
...
public class ProcessorImpl extends ConnectionProcessor<Album> {
protected void processPage(List<? extends Album> resultsPage) {
for(Album result : resultsPage){
System.out.println(result.getAlbumName());
}
}
}
...
public class Album {
public String getAlbumName(){
return "Sweet Smooth SOunds of the 70's";
}
}