# Cast zwischen zwei Unterklassen der selben Oberklasse.



## Joltan (29. Jun 2005)

Habe hier ein kleines Verständnisproblem bezüglich Vererbung:


```
public static void main(String[] args) {
        // TODO code application logic here
        ServerList sl = new ServerList();
        ListServer ls = new ListServer();
        QueryServer qs = new QueryServer();
        qs = (QueryServer)((baseServerClass)ls);
    }
```

bringt mir eine ClassCastException - obwohl beide Klassen von 'baseServerClass' abstammen:

```
public class baseServerClass {
    public long ID;
    public baseServerClass() {  
    }    
}
```


```
public class QueryServer extends baseServerClass {
    public QueryServer() {
    }   
}
```


```
public class ListServer extends baseServerClass {
    public String alias;
    public static long newID = 0;
    public ListServer() {
        this.ID = ++newID;
    }
}
```

Wenn es so nicht geht, wie kann ich dann eine Klasse in die andere und zurück überführen? Mir geht es darum, daß die beiden Klassen später etwa zwei Duzend innere Variablen von 'baseServerClass' erben, aber völlig verschiedene Methoden implementieren werden (ein Interface welches nur Konstanten erlaubt ist daher nicht die Lösung). Gibt's da keine einfachere (und weniger aufwendige) Lösung als Wert für Wert über eine spezielle Importmethode zu übertragen?


----------



## bygones (29. Jun 2005)

Joltan hat gesagt.:
			
		

> ```
> qs = (QueryServer)((baseServerClass)ls);
> ```


der cast ist auch nicht schlüssig.

ls zu baseServerClass zu casten ist kein Problem, da es eine Oberklasse von ServerList ist. Der cast danach ist aber nicht möglich, da es sich nicht um eine QueryServer handelt.

1. ServerList hat nix mit QueryServer zu tun
2. Cast zur Unterklasse ist nicht möglich.

dein Problem versteh ich in der Hinsicht nicht was das mit dem caste zu tun hat ? warum arbeitest du nicht nur mit der Oberklasse weiter egal als welche Unterklasse die Variable initialisiert wurde ?


----------



## Joltan (29. Jun 2005)

Ganz einfach: die jeweiligen Instanzen der zwei Klassen repräsentieren den selben Server haben jedoch unterschiedliche Aufgaben, werden in verschiedenen Threads genutzt und müssen nur gelegentlich synchronisiert werden - d.h. die inneren Variablen welche von der Basisklasse geerbt werden müssen wieder identische Werte enthalten.

Wenn's per cast nicht geht, wie dann? Gibt es eine Entsprechung zu Interfaces, welche aber Variablen anstelle von gemeinsamen Methoden definiert?


----------



## bygones (29. Jun 2005)

abstracte/normale Klassen.

aber ich versteh nicht warum du casten willst. wenn vererbung nimmst und auf die Subklassen angewiesen bist, weil sie eigenen Funktionalitäten definieren, warum casten? sie können automatisch alle nicht private deklarierten Methoden / variablen der Oberklasse nutzen.

aber das Ganze ist anders, wenn es allen Klassen die gleichen Variablen nutzen müssen. Dann ist Vererbung unsinn. da jede instanz seine eigenen Variablen hat und diese Variabeln untereinander nichts zu tun haben.

Dh Subklasse1 arbeitet mit anderen Variablen als Subklasse2, auch wenn sie von der gleichen Superklasse stammen.

Ich vermute du benötigst mehr eine Art ManagerKlasse die für alle Klassen Variablen stellt und für alle Klassen die gleichen Variablen bietet. Dann vergiss Vererbung und schau dir z.b. das Singleton Pattern an....


----------



## Joltan (30. Jun 2005)

Hab's erstmal auf andere Weise gelöst:


```
public class baseServerClass {
    public long ID;
    ...
    /** Creates a new instance of baseServerClass */
    public baseServerClass() {
       ...
    }
    
    public void copyS(baseServerClass bs){
        ID = bs.ID;
        ...
    }
}
```

Auf diese Weise kann ich jede der beiden ineinander überführen ohne zu casten. Werde mir die von Dir erwähnten Singleton Patterns noch anschauen - elegant ist meine Lösung jedenfalls nicht wirklich.

Den cast hatte ich nur verwandt, weil mir klar war, daß ein direktes Überführen der einen Unterklasse in die andere nicht möglich ist.


----------



## Bleiglanz (30. Jun 2005)

```
Apfel ls = new Apfel(); // extends Obst
        Birne qs = new Birne(); // extends Obst
        qs = (Birne)((Obst)ls);
```
ist doch totaler Nonsense gewesen: du kannst einen Apfel nicht in eine Birne verwandeln, selbst wenn beide "Obst" sind....

das Hochcasten hat in deinem Fall nur den Compiler ausgetrickst, beim Runter-Casten fliegt dann eben ein Laufzeitfehler


----------



## Guest (30. Jun 2005)

Naja, das ist klar - ich hatte einfach nur nach einer einfachen Möglichkeit gesucht die für 'Obst' allgemein geltenden Eigenschaften wie 'Zustand' (frisch, vergammelt), 'Herkunftsland', etc. gleichzusetzen. Die spezifischen Eigenschaften von Äpfeln und Birnen sind dabei ja nicht betroffen.

In meinem konkreten Fall geht es im Gegensatz zu zwei verschiedenen Obstsorten allerdings um zwei verschiedene Beschreibungen für ein und den selben Server - die eine Subklasse (Klasse QueryServer) hat alle Funktionalität den Server abzufragen und die Rückgabe zu parsen, während die andere Klasse (Klasse ListServer) bei der Instanzierung eine eindeutige ID erzeugt, sonst aber keine speziellen Methoden implementiert und ausschließlich für die Verwaltung und Anzeige der Rückgabewerte (= innere Variablen der Basisklasse) genutzt wird (in einer speziellen ArrayList).

Zu Beginn wird für jedes ListServer Objekt ein entsprechendes QueryServer Objekt generiert. Die QueryServer Objekte fragen in einem seperaten Thread in einer Schleife immer wieder ihre ensprechenden Server ab, und werden nur nach einer erfolgreichen Anfrage mit dem entsprechenden ListServer Objekt synchronisiert. Derweil greifen andere Programmteile ausschließlich auf die ListServer Objekte zu.

Wie gesagt, über die in der Oberklasse implementierte CopyS-Methode hab ich's ja nun gelöst, hatte aber in meiner Unwissenheit gedacht es einfacher lösen zu können. Aber ich bin ja auch hier um zu lernen!


----------



## Joltan (30. Jun 2005)

Uhm, das war von mir (vergessen einzuloggen)  

Ich werde mir (sobald ich heute Abend Zeit habe) die Singleton Patterns mal ansehen, vieleicht findet sich da ja noch eine andere Möglichkeit. Nicht das sie jetzt noch nötig wäre, aber ich bin ja neugierig!


----------

