Question

(Working in Java) I have an abstract class with generic typing throughout the whole class:

public abstract class ConnectionProcessor<T>
{
    public void process()
    {
        for (List<T> resultsPage : connection)
        {
            processPage(resultsPage);
        }
    }

    protected abstract void processPage(List<T> resultsPage);
}

I have another class that extends said abstract class, with the following declaration:

public class AlbumProcessor<Album> extends ConnectionProcessor
{
    @Override
    protected void processPage(List resultsPage)
    {
        //Do stuff here specific to Album
    }
}

This declaration works fine, but in processPage I want to do Album-specific things, and I try to avoid casting when I don't need to use it. I would PREFER this to be the method declaration:

protected void processPage(List<Album> resultsPage)

But this doesn't meet the requirements for overriding processPage from ConnectionProcessor. Why is this? How can I get the desired behavior? I would think that in AlbumProcessor I could just plug in <Album> everywhere ConnectionProcessor has <T>, but that just isn't the case.

Was it helpful?

Solution

Try

//extend prameterized version of ConnectionProcessor<T> with Album as actual type argument
public class AlbumProcessor extends ConnectionProcessor<Album> {

instead of

public class AlbumProcessor<Album> extends ConnectionProcessor {

When you do the above you are exteding the raw version of the generic type ConnectionProcessor<T> and introducing a new formal type parameter - Album (like T) which is not an actual type argument in that case.

OTHER TIPS

That's because you didn't bind your super class Generic type T to Album.

Rather, this is what you should do:

public class AlbumProcessor extends ConnectionProcessor<Album>

So, when you'll override your method processPage, (using an IDE), it will generate code as follows:

@Override
protected void processPage(List<Album> resultsPage)
{
    //Do stuff here specific to Album
}
public class AlbumProcessor extends ConnectionProcessor<Album>

Try: -

public class AlbumProcessor extends ConnectionProcessor<Album>
{
    @Override
    protected void processPage(List<Album> resultsPage)
    {
        //Do stuff here specific to Album
    }
}

You need to bind your super class with the type you want to give as a type parameter to your List in your method declaration..

How bout something more like this.

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";
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top