2017-05-26 2 views
1

Hier ist ein Beispiel mit minimalem Code. Die Schnittstelle:Instanziieren Sie eine generische Java-Klasse in einer generischen Klasse

interface Individual<T> { 
    public T getVariableValue(int index) ; 
    public void setVariableValue(int index, T value) ; 

    public int getNumberOfVariables() ; 
    public int getNumberOfObjectives() ; 

    public Individual<T> copy() ; 
} 

Und die Klasse:

public class minimalExample<S extends Individual> { 

    private List<S> doCrossover(List<S> s){ 
     S mom = s.get(0); 
     S dad = s.get(1); 

     int crossoverPoint = 5; 

     S girl = mom.copy(); 
     S boy = dad.copy(); 
     for (int i = 0; i < mom.getNumberOfVariables(); i++) { 
      if(i > crossoverPoint){ 
       boy.setVariableValue(i, mom.getVariableValue(i)); 
       girl.setVariableValue(i,dad.getVariableValue(i)); 
      } 
     } 
     return s; 
    } 
} 

Wenn ich versuche, dies zu kompilieren, erhalte ich:

java: incompatible types: Individual cannot be converted to S 

Welche verwirrend scheint. Bedeutet das Schlüsselwort extends, dass S vom Typ Individuell oder Untertyp sein muss?

+0

Ihre Kopiermethode hat einen Rückgabetyp T nicht S. Ich frage mich, Sie müssen es nicht zu gieße S –

Antwort

1

Das scheint verwirrend. Bedeutet das Schlüsselwort extends, dass S vom Typ Individuell oder Untertyp sein muss?

Ja, aber das bedeutet nicht, dass die Art von einem S ‚s copy() Methode zurückgegeben wird, ist auch ein S. Die Schnittstelle Individual erfordert nur, dass es sich um eine Individual handelt.

Außerdem beobachte ich, dass Ihre Klasse minimalExample den Rohtyp Individual verwendet, während es eine ordnungsgemäß parametrisierte Version verwenden sollte (oder Individual sollte nicht-generisch gemacht werden).

Sie können hier zu stark parametrieren. Muss minimalExample wirklich S anstelle von Individual direkt verwenden? Offensichtlich tut dies diese Beispielklasse nicht, aber vielleicht auch nicht diejenige, die die Frage inspiriert hat.

Auf der anderen Seite, wenn Sie benötigen einen Parameter für die spezifische Art von Individual tun , dann müssen Sie vielleicht zu weiter diese Schnittstelle parametrieren die Art von Objekt seiner copy() Verfahren kehrt zu beschreiben:

interface Individual<T,I extends Individual<T, I>> { 
    public T getVariableValue(int index) ; 
    public void setVariableValue(int index, T value) ; 

    public int getNumberOfVariables() ; 
    public int getNumberOfObjectives() ; 

    public I copy() ; 
} 

Sie könnten dann die Klasse MinimalExample mit der benötigten zusätzlichen Informationen erklären:

public class MinimalExample<T, S extends Individual<T, S>> { 
    // ... 
} 

Und hier ist eine Dummy-Implementierung von Individual, die Sie mit, dass verwenden:

public class ExampleIndividual<T> implements Individual<T, ExampleIndividual<T>> { 

    public T getVariableValue(int index) { return null; } 
    public void setVariableValue(int index, T value) {} 

    public int getNumberOfVariables() { return 0; } 
    public int getNumberOfObjectives() { return 0; } 

    public ExampleIndividual<T> copy() { return new ExampleIndividual<T>(); } 

} 
+0

Sie hatten Recht. Ich habe übermäßig parametrisiert. Die endgültige Lösung in diesem Beispiel wäre, einfach ein generisches zu verwenden und dann Individual an allen anderen Stellen zu verwenden. – FlapKap

1

Die Methode copy() gibt ein Objekt vom Typ "Individual" zurück, das nicht dem Typ "S" zugeordnet werden kann, da S ein Subtyp ist.

Warum werden Mädchen und Junge vom Typ "S" und nicht als Individuum erklärt?

Verwandte Themen