G
Gonzo17
Gast
Servus,
irgendwie bin ich auf ein Konstrukt gestoßen, das ich nicht ganz verstehe. Es geht um Generics, die habe ich vorher selten aktiv verwendet und hab jetzt einen Fall, in dem es durchaus Sinn macht. Allerdings stoße ich dabei an ne Grenze, die ich nicht ganz verstehe. Im Folgenden erläutere ich mal anhand eines Beispiels, wo mein Problem liegt.
Zu Beginn habe ich eine abstrakte Klasse definiert, die ich für alle späteren Implementierungen benutzen möchte. Das sieht so aus:
Dabei ist
selbst ein Interface, da es eben auch verschiedene Typen geben kann. In diesem Fall ist es nicht wichtig, was dieses Interface wirklich bereitstellt, deswegen sieht es für das Beispiel so aus:
Für die verschiedenen Typen erstelle ich Enums, die dann eben Parameter verwalten. Das sieht so aus:
Und die Implementierung selbst schaut folgendermaßen aus:
Dass hier auch nichts weiter geschieht, ist erstmal egal, es geht nur darum, dass die vererbte Methode eben nicht
, sondern wirklich
erwartet! Ginge es beispielsweise um Getter und Setter, dann könnte ich sicherstellen, dass hier nur gewollte, konkrete Subtypen des allgemeinen Interfaces verwendet werden.
Jetzt wird es interessant. An einer anderen Stelle möchte ich nun ein Objekt erzeugen, das auf jeden Fall vom Typ
ist. Ob es jetzt
oder
ist, kann ich nicht sagen, ist mir aber auch relativ egal. Sieht dann in etwa so aus:
Aber Zeile 5 verbietet er mir:
Macht auch keinen Unterschied, wenn ich statt
sowas wie
schreibe. Und wo genau ist das Problem?
Nun, so richtig verstehe ich die Ursache des Fehlers nicht. Deswegen frage ich euch. Irgendwo muss ich einen Denkfehler haben. Denn eigentlich würde ich erwarten, dass diese Methode ein Argument vom Typ
annehmen würde. Tut sie aber nicht. Was genau soll denn da stehen? Kennt jemand einen eleganten Weg das anders zu lösen?
irgendwie bin ich auf ein Konstrukt gestoßen, das ich nicht ganz verstehe. Es geht um Generics, die habe ich vorher selten aktiv verwendet und hab jetzt einen Fall, in dem es durchaus Sinn macht. Allerdings stoße ich dabei an ne Grenze, die ich nicht ganz verstehe. Im Folgenden erläutere ich mal anhand eines Beispiels, wo mein Problem liegt.
Zu Beginn habe ich eine abstrakte Klasse definiert, die ich für alle späteren Implementierungen benutzen möchte. Das sieht so aus:
Java:
public abstract class Abstract<T extends Type> {
public void doSomethingWith(T object) {
System.out.println(object);
}
}
Dabei ist
Code:
Type
Java:
public interface Type {
}
Für die verschiedenen Typen erstelle ich Enums, die dann eben Parameter verwalten. Das sieht so aus:
Java:
public enum Type1 implements Type {
A, B, C;
}
Und die Implementierung selbst schaut folgendermaßen aus:
Java:
public class Implementation1 extends Abstract<Type1> {
}
Dass hier auch nichts weiter geschieht, ist erstmal egal, es geht nur darum, dass die vererbte Methode eben nicht
Code:
Type
Code:
Type1
Jetzt wird es interessant. An einer anderen Stelle möchte ich nun ein Objekt erzeugen, das auf jeden Fall vom Typ
Code:
Abstract
Code:
Implementation1
Code:
Implementation2
Java:
public class Test {
public static void main(String[] args) {
Abstract<?> var = giveMeImplementationForAbstract();
Type test = Type1.A;
var.doSomethingWith(test);
}
public static Abstract<?> giveMeImplementationForAbstract(){
return new Implementation1();
}
}
Aber Zeile 5 verbietet er mir:
The method doSomethingWith(capture#2-of ?) in the type Abstract<capture#2-of ?> is not applicable for the arguments (Type1)
Macht auch keinen Unterschied, wenn ich statt
Code:
<?>
Code:
<? extends Type>
Nun, so richtig verstehe ich die Ursache des Fehlers nicht. Deswegen frage ich euch. Irgendwo muss ich einen Denkfehler haben. Denn eigentlich würde ich erwarten, dass diese Methode ein Argument vom Typ
Code:
Type
Zuletzt bearbeitet von einem Moderator: