Vererbung einer generisch typisierten Methode von einer abstrakten Klasse - Konvertierung in einen bestimmten Typ
-
13-12-2019 - |
Frage
(Arbeiten mit Java) Ich habe eine abstrakte Klasse mit generischer Typisierung in der gesamten Klasse:
public abstract class ConnectionProcessor<T>
{
public void process()
{
for (List<T> resultsPage : connection)
{
processPage(resultsPage);
}
}
protected abstract void processPage(List<T> resultsPage);
}
Ich habe eine andere Klasse, die diese abstrakte Klasse mit der folgenden Deklaration erweitert:
public class AlbumProcessor<Album> extends ConnectionProcessor
{
@Override
protected void processPage(List resultsPage)
{
//Do stuff here specific to Album
}
}
Diese Deklaration funktioniert gut, aber in processPage
Ich möchte tun Album
-bestimmte Dinge, und ich versuche zu vermeiden, zu werfen, wenn ich es nicht brauche.Ich würde es vorziehen, wenn dies die Methodendeklaration wäre:
protected void processPage(List<Album> resultsPage)
Dies erfüllt jedoch nicht die Anforderungen für das Überschreiben processPage
von ConnectionProcessor
.Warum ist das so?Wie kann ich das gewünschte Verhalten erzielen?Ich würde denken, dass in AlbumProcessor
Ich könnte einfach einstecken <Album>
überall ConnectionProcessor
hat <T>
, aber das ist einfach nicht der Fall.
Lösung
Versuchen
//extend prameterized version of ConnectionProcessor<T> with Album as actual type argument
public class AlbumProcessor extends ConnectionProcessor<Album> {
statt
public class AlbumProcessor<Album> extends ConnectionProcessor {
Wenn Sie das Obige tun, erweitern Sie die Rohversion des generischen Typs ConnectionProcessor<T>
und Einführung eines neuen formalen Typparameters - Album
(wie T
), was in diesem Fall kein tatsächliches Typargument ist.
Andere Tipps
Das liegt daran, dass Sie Ihren generischen Superklasse-Typ nicht gebunden haben T
zu Album
.
Vielmehr ist es das, was Sie tun sollten:
public class AlbumProcessor extends ConnectionProcessor<Album>
Also, wenn Sie Ihre Methode überschreiben processPage
, (unter Verwendung einer IDE) wird Code wie folgt generiert:
@Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
public class AlbumProcessor extends ConnectionProcessor<Album>
Versuchen:-
public class AlbumProcessor extends ConnectionProcessor<Album>
{
@Override
protected void processPage(List<Album> resultsPage)
{
//Do stuff here specific to Album
}
}
Sie müssen Ihre Superklasse an den Typ binden, den Sie Ihrer Liste in Ihrer Methodendeklaration als Typparameter angeben möchten..
Wie wäre es mit etwas mehr wie diesem.
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";
}
}