Generics und Wil-dcards

Status
Nicht offen für weitere Antworten.

TheSource

Mitglied
Hallo,

ich habe da ein großes Problem und auch die Suche in diesem Forum bzw Google haben mir nicht geholfen.

Also ich habe folgende Klassen:

Code:
public class ShapeGroup<TShape extends Shape> {
  ...
  public void addShape(TShape shape) {
    ...
  }
}

public class Shape {
  public int color;
  ...
}

public class Circle extends Shape {
   public int radius;
  ...
}

public class Rectangle extends Shape {
  public int lengthX;
  public int lengthY;
  ...
}

Diese Klassen darf ich nicht verändern, auch nichts an den Generics dort, soviel sei vorweg gesagt.

Ich möchte jetzt von außen eine Variable vom Typ ShapeGroup erstellen, allerdings weiss ich zur Entwurfszeit ja noch nicht, ob ShapeGroup vom Typ Shape, Circle oder Rectangle ist, also hab ich mir gedacht benutz ich Wildcards:

Code:
ShapeGroup<?> shpGrp;
shpGrp = new ShapeGroup<Circle>();

soweit sogut, aber wenn ich dann mit "shpGrp.addShape(new Circle(5))" was hinzufügen möchte, erwartet er für die Funktion ein NULL-Objekt weil er nicht erkennt, dass ich dort Circles adden will.
Genauso muss es natürlich auch möglich sein über "shpGrp.getShape(0).getRadius" den Radius zu bekommen.

Wie kann ich dieses Problem beheben, ohne das mir Eclipse Warnings ausgibt und es natürlich syntaktisch richtig ist?

ich bedanke mich schonmal vorweg für eure Antworten.


PS.
Das obige Beispiel ist schnell dahingeschmiert worden, um mein Problem zu verdeutlichen, also über Sinn und Unsinn brauch hier nicht diskutiert werden ;)

mfg
TheSource
 

musiKk

Top Contributor
Ich verstehe das irgendwie nur halb und vom NULL-Objekt habe ich auch noch nichts gehoert, aber vielleicht ist dir mit einem
Code:
ShapeGroup<? extends Shape> shpGrp;
geholfen.
 

TheSource

Mitglied
Hallo,

leider nicht, hatte ich vergessen zu erwähnen, das hatte ich auch schon ausprobiert. Dann erwartet Eclipse auch "null" als Eingangsobjekt.
 

TheSource

Mitglied
Hab ne Lösung gefunden, jedoch entzieht sich dies meiner Logik, naja Java war nie meine Lieblingssprache und wird es auch nie werden.


Habe ne zusätzliche Klasse gebaut um die einzelnen Klasseninstanzen unterzubringen:

Code:
public class ShapeInst<TShape extends Shape> {
  private ShapeCollection<TShape> shpColl;
  ...
}

ShapeInst<? extends Shape> shpInst;

So kann ich dann wunderbar auf die "richtigen" Referenzen der Unterklassen zugreifen, warum aber geht es nicht wenn ich dies direkt auf eine Instanz vom Typ ShapeCollection tue? Vielleicht hat ja jemand dafür noch eine Antwort parat, solange bastel ich das mit diesem Workaround weiter.




mfg
TheSource
 

Illuvatar

Top Contributor
Jaja, Java ist doof und unlogisch und so ;)

Überlegen wir mal:

Eine
ShapeCollection<?>
kann als generischen Typ jede beliebige Klasse haben.

Eine
ShapeCollection<? extends Shape>
kann als generischen Typ jede beliebige Unterklasse von Shape haben.

Also beispielsweise:
ShapeCollection<? extends Shape> coll = new ShapeCollection<Rectangle>();
Und damit willst du jetzt das machen:
coll.addShape (new Circle(5));

Merkst du was? Java macht das genau richtig. Java weiß nicht was für Objekte da rein dürfen, wenn du das mit einem ? deklarierst. Und - wofür denn das Fragezeichen?
Wenn du zur Comile-Zeit nicht weißt was für Objekte da reinkommen, helfen dir Generics rein gar nichts
Deine einzige Möglichkeit also: eine
Code:
ShapeCollection<Shape>

(Was du mit deinem "Workaround" da machst, versteh ich irgendwie grad nicht. Ist auch bisschen wenig Code zum nachvollziehen)
 

TheSource

Mitglied
Moin,

Jaja, Java ist doof und unlogisch und so icon_wink.gif

Naja, was heisst hier doof. Entweder man liebt es oder man hasst es :lol:

Eine
ShapeCollection<?>
kann als generischen Typ jede beliebige Klasse haben.

Eine
ShapeCollection<? extends Shape>
kann als generischen Typ jede beliebige Unterklasse von Shape haben.

Also beispielsweise:
ShapeCollection<? extends Shape> coll = new ShapeCollection<Rectangle>();
Und damit willst du jetzt das machen:
coll.addShape (new Circle(5));

Ja, da stimm ich dir zu, ich dachte nur ich mache ihm den Typen bekannt sobald ich
eine neue Instanz eines Objektes kreier. Dies erwies sich als falsch.

(Was du mit deinem "Workaround" da machst, versteh ich irgendwie grad nicht. Ist auch bisschen wenig Code zum nachvollziehen)

Das mit meinem "Workaround" ging nach hinten los, hatte nachher doch wieder das selbige Problem.

Code:
ShapeCollection<Shape> shpColl;
shpColl = new ShapeCollection<Circle>();

Das würde ja jetzt aber nicht gehen, da ich dem Compiler gesagt habe, es sollen doch bitte nur Elemente vom Typ
<Shape> in der ShapeCollection benutzt werden und nicht noch die unter Klassen. In Delphi geht das z.B. alles super,
dort kann man dann auch (Shape as Circle).... ein Cast auf die eigentliche Unterklasse machen, um deren Funktionalität zu erhalten.

Du scheinst ja recht viel Ahnung in Java zu haben, erklär mir doch bitte wie ich dieses Problem lösen kann.



mfg
TheSource
 

Illuvatar

Top Contributor
Ich denke, das Problem wird sich ohne Casts nicht lösen lassen. Du weißt eben bei der Deklaration der Collection nicht, was da später für ein Typ reinsoll, richtig? Mit den Wildcards kannst du nur erreichen, dass du später Collections von unterschiedlichen Typen an die Variable zuweisen kannst. Damit verlierst du aber auch ein bisschen Wissen darüber, was denn jetzt genau der Typ der Collection sein soll.

Vielleicht ist es leichter, wenn man sich das wie Arrays vorstellt. Ohne Wildcards kannst du nur ein Shape[] erstellen. Dieser Variable kann man aber kein Circle[] zuweisen. Deswegen gibt es (bei Generics) Wildcards, also sozusagen (? extends Shape)[]. Dieser Variable kannst du so einiges zuweisen, z.B. ein Circle[] oder ein Rectangle[]. Aber was du zuweist, das weiß der Compiler nicht. Für den Compiler ist das immer noch ein (? extends Shape)[]. Der Compiler weiß, was auch immer da rauskommt, ist ein Shape. Aber was genau reinmuss, weiß er nicht.

Ich sehe 3 Möglichkeiten, ich weiß nicht welche jetzt bei dir funktionieren:
  • Du machst von Anfang an nur eine ShapeCollection<Shape> - kannst dann auch auf der rechten Seite nur eine ShapeCollection<Shape> zuweisen.
  • Du machst mehrere Collections, eine für jeden Typ, und musst halt irgendwie abfragen, welche die richtige ist (oder kannst du evtl. gleich nur die erstellen die du brauchst?)
  • Vielleicht am besten: Du machst weiter deine
    Code:
    ShapeCollection<? extends Shape> shapeColl
    Füllen kannst du die ja z.B. so (da wo du füllst, kennst du den Typ ja):
    Code:
    ShapeCollection<Circle> newColl = new ShapeCollection<Circle>();
    newColl.addShape (new Circle(5));
    shapeColl = newColl;
    Da wo du dann Objekte rausholen willst, musst du dann eben ne Fallunterscheidung machen, je nach dem was drin ist, in der Art (Achtung, fliegt dir um die Ohren wenn die Collection leer ist):
    Code:
    if (newColl.getShape(0) instanceof Circle) {
      ShapeCollection<Circle> castedColl = (ShapeCollection<Circle>)shapeColl;
      Circle c = castedColl.getShape(0);
    }
 

TheSource

Mitglied
Hi,

danke, das mit den Wildcards hab ich jetzt verstanden.
Ich werde deine Variante mit den Casts benutzen. Funzt einwandfrei, bin zufrieden.


Nochmals danke.


mfg
TheSource
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Best Practice Generics mit Enum Allgemeine Java-Themen 3
H Kombination Interface und Abstrakte Klasse bei Generics Allgemeine Java-Themen 3
Zeppi Cast Object in Generics Allgemeine Java-Themen 4
P Generics und Arrays Allgemeine Java-Themen 6
M Generics / Typen Allgemeine Java-Themen 1
Kirby.exe InsertionSort mit Generics Allgemeine Java-Themen 33
Kirby.exe Vererbung bei Generics Allgemeine Java-Themen 7
H Klarnamen etc... (von Wie Generics lernen?) Allgemeine Java-Themen 26
D Wie Generics lernen? Allgemeine Java-Themen 26
L Compiler-Fehler Generics beim Anhängen von Predicates Allgemeine Java-Themen 1
W Vererbung Generics - mal wieder die verhaßte Rückwärtskompatibilität Allgemeine Java-Themen 2
S Verstaendnisfrage Generics Allgemeine Java-Themen 19
W Generics + Vererbung Allgemeine Java-Themen 47
I Methoden Generics-Methode Allgemeine Java-Themen 3
D Mit Generics arbeiten - Übungsaufgabe Allgemeine Java-Themen 3
K Factory Pattern: Mit Generics umgehen Allgemeine Java-Themen 6
G Generics Allgemeine Java-Themen 31
perlenfischer1984 Liste mit generics zurück liefern Allgemeine Java-Themen 8
Hacer Generics & Collections Allgemeine Java-Themen 8
Neumi5694 Interface Generics für Enum-Filterung verwenden Allgemeine Java-Themen 5
H Collector Generics Problem (incl. Stream & Lambda) Allgemeine Java-Themen 4
C Gemeinsame Oberklasse zweier Generics Allgemeine Java-Themen 10
erdmann Datentypen Methodendeklaration mit Generics Allgemeine Java-Themen 2
Z Datentypen Verschachtelte Generics Allgemeine Java-Themen 1
Neumi5694 Datentypen Generics Allgemeine Java-Themen 5
S Mit Generics Klasse erstellen die selbst T erweitert..? Allgemeine Java-Themen 4
Tarrew Generics - Type erasure Allgemeine Java-Themen 5
N Problem mit Generics und Interface Allgemeine Java-Themen 4
H Generics als Parameter Allgemeine Java-Themen 1
kaoZ Generics und Vererbung Allgemeine Java-Themen 3
A Datentypen Generics: Wie am besten auf Typparameter zugreifen Allgemeine Java-Themen 2
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
vandread Kleine Generics Aufgabe aus einer Prüfung... wie ist das gemeint? Allgemeine Java-Themen 6
G Generics sind zu streng - oder ich zu naiv? Allgemeine Java-Themen 3
G Verschachtelte Generics Allgemeine Java-Themen 2
O Generics Allgemeine Java-Themen 42
M Problem mit Generics Allgemeine Java-Themen 10
M Generics (bounded wildcards statt Interface Bezeichnern) -- Sinn oder Unsinn? Allgemeine Java-Themen 2
darekkay Generics: Wildcard und Object Allgemeine Java-Themen 5
H Collections Generics und Reflection Allgemeine Java-Themen 6
F Google Guice + Generics + Vererbung Allgemeine Java-Themen 5
H Problem mit Java Generics Allgemeine Java-Themen 6
J Generics: Typparameter als Klasse zurückliefern Allgemeine Java-Themen 4
H Generics Allgemeine Java-Themen 5
P Probleme mit Generics Allgemeine Java-Themen 5
B Generics und primitve arrays Allgemeine Java-Themen 6
M Generics Allgemeine Java-Themen 11
1 Collections Generics, internes Verhalten Allgemeine Java-Themen 16
T Warnungsfreie Verwendung von Generics Allgemeine Java-Themen 11
M Probleme mit Generics Allgemeine Java-Themen 5
D Java Generics Allgemeine Java-Themen 8
2 Generics: bounded wildcards Allgemeine Java-Themen 4
J Generics / vermeiden von downcasts Allgemeine Java-Themen 2
2 Generics oder nicht? Allgemeine Java-Themen 8
E Problem mit Generics und Comparable Allgemeine Java-Themen 16
W Erweitern einer Klasse mit Generics Allgemeine Java-Themen 8
H Generics für Methode Allgemeine Java-Themen 14
N Überladen mit Hilfe von Generics Allgemeine Java-Themen 3
S Generics: Fuer Set<T> ein T-Klassenobjekt erhalten? Allgemeine Java-Themen 3
Q Der innere Typ von Generics? Allgemeine Java-Themen 3
N Generics-NullpointerException Allgemeine Java-Themen 7
2 Generics - Typ Allgemeine Java-Themen 12
P Generics Problem Allgemeine Java-Themen 10
S Type safety Warnings beim casten von Generics Allgemeine Java-Themen 6
N Generics Allgemeine Java-Themen 3
V Frage zu Generics Allgemeine Java-Themen 2
S java generics klassen deklaration Allgemeine Java-Themen 7
B hashtable für unterschiedliche Typen - mit Generics Allgemeine Java-Themen 8
E Generics Allgemeine Java-Themen 3
MQue Generics Allgemeine Java-Themen 4
R Problem mit Reflection und Generics Allgemeine Java-Themen 3
C Klassen, die aufeinander verweisen (mit Generics) Allgemeine Java-Themen 16
G Generics - W.card unter Nutzung von Annotationsklasse? Allgemeine Java-Themen 6
G sortieren von generics Allgemeine Java-Themen 10
G Generics in Map. Type of value abhängig vom key Allgemeine Java-Themen 3
A Generics Verständnisfrage Allgemeine Java-Themen 7
Z Generics funzt nicht? Allgemeine Java-Themen 2
T Generics Allgemeine Java-Themen 18
G ComboBox: Nur eine Art Klasse zulassen (Generics) Allgemeine Java-Themen 3
J Generics Expertenwissen? Allgemeine Java-Themen 5
S Generics-Problem Allgemeine Java-Themen 3
Q Typen von Generics & Casten Allgemeine Java-Themen 3
S Generics Allgemeine Java-Themen 2
R Problem mit Generics Allgemeine Java-Themen 2
G Trotz Generics Cast-Fehler! Allgemeine Java-Themen 5
T TreeMap durch Comparator mit Generics sortieren Allgemeine Java-Themen 9
T Generics und instanceof Allgemeine Java-Themen 10
T Generics und Exceptions Allgemeine Java-Themen 6
M Beliebig viele Typen bei Generics Allgemeine Java-Themen 3
G Reflection objekt mit generics erzeugen Allgemeine Java-Themen 5
S Singleton Pattern mit Generics Allgemeine Java-Themen 4
G Generics und Comparable Allgemeine Java-Themen 11
H Generics Problem Allgemeine Java-Themen 3
F Generics: spricht etwas dagegen raw types zu verwenden? Allgemeine Java-Themen 31
M Generics - besser programmieren, Warnung umgehen Allgemeine Java-Themen 4
E Java, UML, Generics Allgemeine Java-Themen 6
P Array von Vectoren + Generics Allgemeine Java-Themen 6
M ArrayList erweitern - generics Allgemeine Java-Themen 4
E Generics -> UML Allgemeine Java-Themen 4
G Generics: Instanzieren einer Klasse in einer Methode. Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben