2016-06-01 10 views
0

Ich versuche herauszufinden, wie (wenn es sogar möglich ist) den Basisrückgabetyp ändern, wenn der Typ noch an eine abstrakte Klasse übergeben werden muss. (Es tut mir leid für eine so milde Erklärung, aber ich habe wirklich keine Ahnung, wie man besser das erklären)Abstrakte Oberklasse übergibt Supertype an Rückgabetyp

// Base Profile and Repository 
public abstract class BaseProfile { } 
public abstract class BaseRepository<T extends BaseProfile> { 
    public abstract T doSomething(String name); 
} 

// Enhanced Profile and Repository 
public abstract class EnhancedProfile extends BaseProfile { 
    public abstract String getName(); 
} 
public abstract class EnhancedRepository<T extends EnhancedProfile> extends BaseRepository<T> { 
} 

// Instance of Repository 
public class InstanceProfile extends EnhancedProfile { 
    @Override 
    public String getName() { return "Hello World"; } 
} 
public class InstanceRepository extends EnhancedRepository<EnhancedProfile> { 
    public EnhancedProfile doSomething() { return null; } 
} 

Nun, was ich will, ist ein EnhancedRepository zu speichern, ohne es zu wissen Klasse geerbt hat und in der Lage die für den Zugriff auf EnhancedProfile, nicht BaseProfile, siehe unten:

// What I want 
EnhancedRepository repo = new InstanceRepository(); 
EnhancedProfile enProfile = repo.doSomething(); 
// Does not work because the doSomething() method actually returns 
// BaseProfile, when I need it to at least return the EnhancedProfile 

// What I know works, but can't do 
EnhancedRepository<InstanceProfile> repo2 = new InstanceRepository(); 
EnhancedProfile enProfile2 = repo2.doSomething(); 
// This works because I pass the supertype, but I can't do this because I need 
// to be able to access EnhancedProfile from the doSomething() method 
// from a location in my project which has no access to InstanceProfile 

Wie kann ich die EnhancedProfile von doSomething() erhalte, anstelle der Basis meist Typen BaseProfile, ohne den übergeordneten Typen von EnhancedRepository zu wissen?

+0

Verwenden Sie keine Rohtypen. Parametriere dein 'Repo' mit einem Platzhalter' '. Seine untere Grenze ist 'EnhancedProfile'. –

Antwort

0

Ein einfacher Weg ist, Generika nicht zu verwenden (scheint in Ihrem Beispiel sinnlos). Stattdessen überschreiben Sie die Methode mit einer spezifischeren Methode

// Base Profile and Repository 
public abstract class BaseProfile { 
} 

public abstract class BaseRepository { 
    public abstract BaseProfile doSomething(String name); 
} 

// Enhanced Profile and Repository 
public abstract class EnhancedProfile extends BaseProfile { 
    public abstract String getName(); 
} 

public abstract class EnhancedRepository extends BaseRepository { 
    @Override 
    public abstract EnhancedProfile doSomething(String name); 
} 

// Instance of Repository 
public class InstanceProfile extends EnhancedProfile { 
    @Override 
    public String getName() { 
     return "Hello World"; 
    } 
} 

public class InstanceRepository extends EnhancedRepository { 
    public EnhancedProfile doSomething(String name) { 
     return null; 
    } 
} 

void whatIWant() { 
    EnhancedRepository repo = new InstanceRepository(); 
    EnhancedProfile enProfile = repo.doSomething(""); 
} 
+0

Mein Beispiel wurde aus einem viel komplexeren Repository entfernt, das ich gebaut habe. Ohne Generika wäre das BaseRepository, das ich tatsächlich nutze, nicht in der Lage, den spezifischen Profiltyp zu erstellen, den ein Entwickler benötigt. –

Verwandte Themen