# Variant-Datentyp



## apfelsine (6. Sep 2004)

Hallo,

ich suche ein äquivalent zum Datentyp Variant aus VB

Hintergrund ist, das nicht bekannt ist, welcher Datentyp an
das Objekt  übergeben werden wird.
hat jemand einen Tip?
Danke schonmal im Vorraus!

apfelsine


----------



## Reality (6. Sep 2004)

Du kannst ja mehrere Konstruktoren oder Methoden erstellen mit verschiedenen Parametern bzw. Typen. Die richtig Methode wird dann automatisch aufgerufen.

Liebe Grüße
Reality


----------



## Anubis (6. Sep 2004)

Für Elementare Datentypen gibt es sowas nicht. Aber es gibt für jeden Elementaren Datentyp eine Wrapperklasse (zb. Die Integer-Klasse (Schaue in der API nach). 
Und ALLE Klassen sind in Java eine Erweiterung von Object. WEnn du also eine Variable folgendermaßen deklariert:
	
	
	
	





```
Object var;
```
, dann kannst du in var alles reinpacken, was ein Obejct ist.


----------



## meez (6. Sep 2004)

apfelsine hat gesagt.:
			
		

> Hallo,
> ...Hintergrund ist, das nicht bekannt ist, welcher Datentyp an...



1. Software Design ändern...
2. Interface verwenden...


----------



## Thorsten (6. Sep 2004)

Ähmmm  ???:L 

Das geht nicht! Es muss der Datentyp vorher bekannt sein. Und mir ist kein Fall
bekannt, in dem das nicht geht  :wink: Von wo erhälst du denn ein unbekanntes
Objekt?

In Java sind ALLE Objekte von Object vererbt. Also kannst du immer mit Object
arbeiten.

Aber gib mal ein Beispiel  :toll: Ich will mal sehen, wo du ein unbekanntes
Objekt her bekommst  :wink: 

In Java 5 gibt es eine Möglichkeit... mit den Generics oder so. Finde ich aber
nicht so gut, und habs auch nicht im Kopf. Das muss wer anders erklären  :bae:


----------



## P3AC3MAK3R (6. Sep 2004)

Reality hat gesagt.:
			
		

> Du kannst ja mehrere Konstruktoren oder Methoden erstellen mit verschiedenen Parametern bzw. Typen. Die richtig Methode wird dann automatisch aufgerufen.


So würde ich das auch lösen.

Falls Du nähere Infos brauchst, suche am besten nach dem Stichwort "Überladung".


----------



## Thorsten (6. Sep 2004)

Das ging schnell: In drei Minuten so viele Antworten *gg*


----------



## meez (6. Sep 2004)

Thorsten hat gesagt.:
			
		

> In Java sind ALLE Objekte von Object vererbt. Also kannst du immer mit Object
> arbeiten.



Bringt einfach nichts, da du dann auch nur die Methoden von Object verwenden kannst...


----------



## Thorsten (6. Sep 2004)

meez hat gesagt.:
			
		

> Thorsten hat gesagt.:
> 
> 
> 
> ...



Das ist richtig. Aber er kann zumindest ein "unbekanntes Objekt" aufnehmen.
Wir wissen ja nicht, was er vorhat. Wenn er es nur auf die Festplatte schreiben
will, geht das. 

Aber wenn er den "echten" Zieltyp auf eine handvoll einschränken kann, kann er
in einem großen if-Konstrukt in einer try-catch-Schleife versuchen das richtige
Objekte zu finden. Das würde gehen --> also eine Art cast-Filter  8) 

Es gibt auch noch einen unerklärlichen Effekt beim vererben, mit dem man
so einen cast-Filter realisieren kann. Bei Interesse kann ich es zeigen


----------



## foobar (6. Sep 2004)

> Es gibt auch noch einen unerklärlichen Effekt beim vererben, mit dem man
> so einen cast-Filter realisieren kann. Bei Interesse kann ich es zeigen


Zeig mal


----------



## Thorsten (6. Sep 2004)

Also das Hauptprogramm / Main-Methode:


```
import java.util.Vector;

public class Cast
{
   private static Vector vec;
   
   private static mnSprites mySprite;
   private static mnMusic myMusic;
   private static mnObject myObject;

   public static void main(String[] args)
   {
       mySprite = new mnSprites("grafik");
       myMusic = new mnMusic("musik");

       vec = new Vector();
       vec.add(mySprite);
       vec.add(myMusic);

       for (int i = 0; i<2; i++)
       {
          myObject = (mnObject) vec.get(i);
          myObject.castIntoOwnClass(myObject);
       }
   }
}
```

Klasse mnObject:

```
public abstract class mnObject
{
   public mnObject()
   {
   }

   public abstract void castIntoOwnClass(mnObject myObject);
}
```

Klasse mnMusic:

```
public class mnMusic extends mnObject
{
   String Inhalt;

   public mnMusic(String Inhalt)
   {
      this.Inhalt = Inhalt;
   }

   public void castIntoOwnClass(mnObject myObject)
   {
      mnMusic myMusic = (mnMusic) myObject;
      workWithIt(myMusic);
   }

   private void workWithIt(mnMusic myMusic)
   {
      System.out.println(myMusic.Inhalt);
   }
}
```

Und die Klasse mnSprite:

```
public class mnSprites extends mnObject
{
   String Inhalt;

   public mnSprites(String Inhalt)
   {
      this.Inhalt = Inhalt;
   }

   public void castIntoOwnClass(mnObject myObject)
   {
      mnSprites mySprite = (mnSprites) myObject;
      workWithIt(mySprite);
   }

   private void workWithIt(mnSprites mySprite)
   {
      System.out.println(mySprite.Inhalt);
   }
}
```

Im Prinzip darf dieser Code nicht funktionieren. Aber er geht!  ???:L  Ist also irgendwie unerklärlich,
wie Java weiß, welches Objekt nun welches ist...

Aber man kann es schon ahnen:
Wenn man Objekte zum Beispiel per XML auf die Festplatte schreibt, dann speichert auch den
Objekttyp mit. Java weiß also intern, welches Objekt von welchen Typ ist. Schade, dass es
dann kein casten per Variable in Java gibt, also:


```
private String castTo = "Integer";
Integer bla = (castTo) meinVector.get(n)
```

Sowas in der Art... also das Cast-Ziel per String angeben. Das wäre cool. Denn offentsichtlich
kennt Java ja doch den Datentyp intern...


----------



## Bleiglanz (6. Sep 2004)

>>Im Prinzip darf dieser Code nicht funktionieren.

warum?  Stichwort polymorhie

>> Aber man kann es schon ahnen: Wenn man Objekte zum Beispiel per XML 

hä? was ist das?

>>auf die Festplatte schreibt, dann speichert auch den
>>Objekttyp mit. Java weiß also intern, welches Objekt von welchen Typ ist.

willkommen in der Java welt

>> Schade, dass es dann kein casten per Variable in Java gibt, also:
>> castTo = "Integer"; Integer bla = (castTo) meinVector.get(n) 

total derangiert, so eine Funktion wäre in Java definitv sinnlos, weil links "Integer bla" steht, muss rechts sowieso Integer stehen


----------



## Thorsten (6. Sep 2004)

MammutsknochenAusAstrakan hat gesagt.:
			
		

> >Im Prinzip darf dieser Code nicht funktionieren.
> warum?  Stichwort polymorhie



Schlaumeier, was? :roll: 
Das ist schon klar. 

Der Vector liefert mit der get-Methode aber einen Rückgabewert
Object. Nun caste ich diesen in mnObject. mnObject ist aber abstrakt.

*mnObject hat im Prinzip keine Ahnung, ob er nun mit mnMusic oder
mnSprite weiter machen soll.*

Woher soll er das wissen? 

Aber er weiß es eben doch... merkwürdiger weise... 



> >> Aber man kann es schon ahnen: Wenn man Objekte zum Beispiel per XML
> hä? was ist das?



Du weißt nicht, was XML ist, spuckst aber große Töne, was? :roll:
Ich werde XML jetzt nicht erklären. 

Aber mit einem XMLEncoder (java.beans) kann man ein Object in XML
auf die Festplatte schreiben (wenn man einen FileOutputStream benutzt).
Die Klasse XMLEncoder hat die Methode writeObject(). Die Methode 
schreibt also nur Objekte vom Typ Object.

Und beim lesen gibt die Methode nur Object zurück. Also muss man
wieder casten. Und wenn man nicht genau weiß, was für Typen in der
Datei sind? Kann man es vergessen...

Doch Java schreibt den richtigen Datentyp in die XML-Datei, im Klartext.
Das ist eben ärgerlich. Java kennt den Typ im Prinzip, gibt aber natürlich
nur Object zurück...



> >>auf die Festplatte schreibt, dann speichert auch den
> >>Objekttyp mit. Java weiß also intern, welches Objekt von welchen Typ ist.
> willkommen in der Java welt



So klar ist das nicht! Wie gesagt: Man schreibst und liest nur Daten vom Typ
"Object". Da ist es schon wunderlich, dass Java überhaupt den richtigen Datentyp
schreibt...



> >> Schade, dass es dann kein casten per Variable in Java gibt, also:
> >> castTo = "Integer"; Integer bla = (castTo) meinVector.get(n)
> total derangiert, so eine Funktion wäre in Java definitv sinnlos, weil links
> "Integer bla" steht, muss rechts sowieso Integer stehen



So ein Blödsinn. Hast überhaupt Ahnung?

Wie ich schon geschrieben habe: get() von Vector liefert ein Object zurück.
Man muss also casten. 


Nun stelle man sich vor, man wolle ein Actionspiel mit Java programmieren.
Ich habe also Klassen wie Krieger, Spieler, Rüstungen, Inventar etc. pp.

Wenn ich die Objekte dieser Klassen in eine Datei schreibe, muss ich sie
als Object schreiben.

Beim lesen hab ich dann ein Problem:
Wie weiß ich jetzt, was für ein Objekt ich habe? Inventar? Spieler? ...
Da wäre es schon interessant das Cast-Ziel dynamisch zu wählen. 
Mit tray-catch könnte man dann das richtige Ziel schnell finden.

Oder eine Methode getNextTyp() beim XMLDecoder oder beim ObjectInputStream
wäre genau das Richtige. Wäre ja kein Problem für Sun. Aber leider gibt es das
nicht.


----------



## bygones (6. Sep 2004)

Zum ersten erbitte ich mir hier keine Beleidigungen - man kann das Ganze auch auf eine nette Art und Weise vermitteln !



			
				Thorsten hat gesagt.:
			
		

> Der Vector liefert mit der get-Methode aber einen Rückgabewert
> Object. Nun caste ich diesen in mnObject. mnObject ist aber abstrakt.
> 
> *mnObject hat im Prinzip keine Ahnung, ob er nun mit mnMusic oder
> ...


Sorry das Problem versteh ich nicht... Die methode get liefert natürlich den Typ Object zurück weil die Klasse Collection keine Ahnung hat was für Objekte reingesteckt werden. Beim ausführen aber ist Java klar was für ein Datentypo verwendet wird - auch sonst wären die generelle Verwendung von Interfaces / abstrakten Klasse unsinnig ?!

PS: mit den Generics ab 1.5 ist das Problem dann sowieso obsolet !


----------



## bygones (6. Sep 2004)

Thorsten hat gesagt.:
			
		

> Wenn ich die Objekte dieser Klassen in eine Datei schreibe, muss ich sie
> als Object schreiben.
> Beim lesen hab ich dann ein Problem:
> Wie weiß ich jetzt, was für ein Objekt ich habe? Inventar? Spieler? ...
> ...


muss nicht try / catch sein - instanceof ginge auch. Aber du könntest einen delimiter schreiben oder die Objekte in eine Collection oder Map z.b. packen und dann die Collection / Map schreiben - dann ersparst du dir das komplizierte lesen....


----------



## apfelsine (6. Sep 2004)

Ich sehe, ich habe eine streitbare Frage gestellt
 
Auf jeden Fall schonmal danke für die ausführlichen Antworten,
das bringt mich schon viel weiter.

apfelsine  :wink:


----------



## Thorsten (6. Sep 2004)

deathbyaclown hat gesagt.:
			
		

> Thorsten hat gesagt.:
> 
> 
> 
> ...



Super  :toll: instanceof war mir noch unbekannt    Das muss ich mir merken :wink: 
Was ist ein Delimiter?


----------



## bygones (6. Sep 2004)

Thorsten hat gesagt.:
			
		

> Super  :toll: instanceof war mir noch unbekannt    Das muss ich mir merken :wink:
> Was ist ein Delimiter?


instanceof ist vor allem programmiertechnisch besser als zig exceptions handlings..

delimiter = Begrenzer. Soll heißen du liest solange Objecte ein bis ein definierter Delimiter kommt (was weiß ich, in integer oder so), dann weißt du dass z.b. eine andere Klasse nun folgt usw. 

aber wie gesagt - entweder mit instanceof oder in eine collection oder map packen und die serialisieren


----------



## Bleiglanz (6. Sep 2004)

```
Wie weiß ich jetzt, was für ein Objekt ich habe? Inventar? Spieler? ...
Da wäre es schon interessant das Cast-Ziel dynamisch zu wählen.
Mit tray-catch könnte man dann das richtige Ziel schnell finden.
```

Es hat keinen Sinn, ein Cast-Ziel dynamisch zu wählen, wohin willst du denn casten: du kannst das Ergebnis ja nicht in eine Variable legen (es sei denn, es gibt einen gemeinsamen Obertypen - z.B. ein Interface - aber dann könntest du gleich in diesen Obertyp casten)?

Angenommen du nimmst ein Object o = list.get(0) aus einer Collection. Was dann?  Jetzt soll dynamisch was passieren, abhängig vom Typ von o.

=> mach ein paar if(o instanceof )...

=> oder mach o.getClass().getName() und dann die ifs

usw. Wenn du dann den Typ kennst, kannst du ja mit T t = (T) o; casten usw.

Kannst du mal erklären, wie ein dynamischer cast funktionieren sollte????


----------

