Наследование универсального типизированного метода от абстрактного класса — преобразование в определенный тип

StackOverflow https://stackoverflow.com//questions/12716589

Вопрос

(Работаю на 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";
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top