Inheritance of generic typed method from abstract class — convert to specific type
-
13-12-2019 - |
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.
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";
}
}