Vererbung Queue bestehend aus Superclass- und Subclass-Objekten

Nick9051

Mitglied
Hi,

ich baue eine polymorphe Queue aus Objekten einer Superclass und einer Subclass.

Mein Problem:
Die Subclass-Elemente haben einen extra-Wert.
Die Elemente sollen weiter in der Queue nach vorne rücken desto höher dieser Wert ist.
Beispiel:
A ist ein Objekt der Superclass.
B ist ein Objekt der Subclass mit dem Wert 1.
C ist ein Objekt der Subclass mit dem Wert 2.
Eingefügt wird in der Reihenfolge (A -> B -> C)
Nach dem Einreihen aller Objekte soll die Reihenfolge folgende sein: C, B, A. Wobei C das vorderste Element ist.

Meine Fragen:
Wie überprüfe ich, ob ein Element meiner Queue ein Element der Subclass ist? (Mit instanceof ?)
Wie bekomme ich den Wert des Objektes, um ihn mit meinem neuen Wert zu vergleichen?

Danke schonmal für eure Hilfe. Ich verzweifle leicht.
Code kann ich beifügen wenn gewünscht, ist aber mMn relativ unübersichtlich.

VG
 
Möglicherweise hast du deine Superclass und Subclass falsch geplant.
Kann nicht die Superclass das Element kennen (zumindestens als get-Methode), das dann immer auf einem niedrigen Wert (beispielsweise 0) steht.

Das Benutzen von instance of ist zwar möglich, aber oft ein Zeichen von einem Designfehler.
 
Im Anhang hier ein UML-Diagramm vom Problem.
Das stammt aus einer Aufgabe aus der Uni.
Ich hatte angenommen, dass zusätzliche Methoden oder Variablen nicht erlaubt sind, weswegen ich keine weiteren getter und setter eingebaut habe.
 

Anhänge

Das konnt ich ja nicht ahnen: Wenn das Beispiel von der Uni stammt, musst du natürlich mit instanceof arbeiten.
Es bleibt aber richtig, dass du außer bei solchen Übungen, das instanceof als "Geschmäckle" betrachten solltest.
 
Hast du denn ne Idee wie ich die Variable aus der Subklasse bekomme nachdem ich die Abfrage gemacht habe ob es ein Objekt der Subklasse ist?
 
Ich denke im Endeffekt liegt mein Problem beim Polymorphismus / bei den Generics.
Kannst du / könnt ihr mir sagen woran das liegt und wie ich die Queue generic halten kann, sodass man sowohl Node und BribeNode als "next" nutzen kann? Sonst funktioniert die ganze Queue so ja nicht, oder?


[CODE lang="java" title="Node.java"]
public class Node <T>{
public T value;
public Node <T> next;
public Node <T> previous;
}
[/CODE]

[CODE lang="java" title="BribeNode.Java"]
public class BribeNode<T> extends Node<T> implements Bribable {
protected long bribery;
@Override
public long getBribery() {
// TODO Auto-generated method stub
return this.bribery;
}
}
[/CODE]

[CODE lang="java" title="PreorderQueue.java" highlight="39-69"]
public class PreorderQueue<T> {
public Node<T> first;

public PreorderQueue(){
}


public Boolean isEmpty() {
if (this.first != null) {
return false;
}
else return true;
}


public void preorder(T value) {
if (value != null) {
if (this.first == null) {
this.first = new Node<T>();
this.first.value = value;
}
else {
Node<T> temp = new Node<>();
temp = this.first;
while (temp.next != null) {
temp = temp.next;
}
temp.next = new Node<>();
temp.next.value = value;
}


}
}



public void preorderWithBribery(T value, long bribery) {
if (bribery <= 0) {
throw new IllegalArgumentException("Der Wert ist zu klein");
}
System.out.println("Test auf Bribery");

Node<T> temp = new Node<>();
BribeNode<T> bribe = new BribeNode<>();
bribe.value = value;
bribe.bribery = bribery;

if (value != null) {
if (this.first == null) {
this.first = bribe;
}
else if (this.first instanceof BribeNode) {
System.out.println("first ist bribery");


}


}
else if(!(this.first instanceof BribeNode)){
System.out.println("first ist kein bribery");
temp = this.first;
this.first = bribe;
this.first.next = temp;
}

}

public T processPreorder() {
Node<T> temp = this.first;
if (this.first == null) {
throw new NullPointerException("Die Schlange ist leer");
}
if (this.first.next == null) {
this.first = null;

}
else if (this.first.next != null) {
this.first = this.first.next;
}
return temp.value;
}

public T getFirstPreorder() {
if (this.first == null) {
throw new NullPointerException("Die Schlange ist leer");
}
else {
return this.first.value;
}
}


}[/CODE]
 
Ich denke im Endeffekt liegt mein Problem beim Polymorphismus
Das erste, was Du verstehen musst, ist dass eine Referenzvariable (Variable komplexen Typs) nicht das Objekt speichert sondern nur die Referenz darauf. Insofern gibt z. B. Deine Zeile 23 in Verbindung mit 24 überhaupt keinen Sinn: Du erzeugt ein neues Node-Objekt, speicherst dessen Referenz in temp ab und überschreibst temp im nächsten Schritt mit this.first. In Zeilen 28 und 29 verhält es sich anders: dort wird in Zeile 29 auf value des zuvor erzeugten Nodes zugegriffen.

Das zweite ist, dass der im Quelltext deklarierte Typ einer Referenzvariablen dem Compiler sagt, wie er die Objekte betrachten soll, wenn die Variable verwendet wird. Zuweisen kannst Du Objekt des deklarierten oder eines davon (direkt oder indirekt) abgleiteten Typs.

Dein first ist vom Typ Node<T>, daher kannst Du normalerweise auch nur auf die Methoden und Variablen zugreifen, die von Node<T> (oder eines Supertyps) deklariert wurden.

Das ist nicht anders wie hier:
Java:
String text = "ABC";
Object value = text; // Zuweisung ist ok, das String von Object abgeleitet ist

System.out.println(text.length()); // OK, da text vom Typ String ist und String die Methode length() definiert
System.out.println(value.length()); // Nicht OK, da value vom Typ Object ist und Object die Methode length() nicht kennt.

Was Du tun kannst, ist dem Compiler zu sagen, dass er value so behandeln soll, als wäre die Variable vom Typ String. Das erledigt man mit einem Cast:
Java:
String valueAsString = (String) value;
System.out.println(valueAsString.length()); 
// oder ohne zusätzliche Variable:
System.out.println( ((String) value).length() ); // die zusätzlichen Klammern sind notwendig, da der Punkt-Operator Vorrang vor dem Cast hat

Auf Dein Problem umgemünzt, z. B.
Java:
if (first instanceof BribeNode) {
    BribeNode<T> bribeFirst = (BribeNode<T>) first;
    // ...
}

Nebenbei: Du hast das UML nicht richtig umgesetzt: die Instanzvariablen sind dort private.
 

Neue Themen


Zurück
Oben