# Eigener Datentyp?



## Alexander (13. Okt 2004)

Hallo,
ich programmiere eigentlich nur in Delphi/Pascal und habe von JAVA eigentlich nicht so die Ahnung ;-)
Nun sollen wir in Info irgendein Projekt in JAVA basteln, ich habe mich für einen mathematischen Parser mit Termbaum entschieden. Das ist eigentlich alles auch schon auf'm Papier fertig ;-). Nur jetzt kommt halt noch die Umsetzung und das Überprüfen, ob's überhaupt richtig ist, was ich da fabriziert habe ;-)

So und jetzt möchte ich für die Operatoren einen eigenen Datentyp erstellen. In Delphi konnte ich einfach das so machen:

```
TTest   = (A, B, C);
```
So nun hätte ich einen Datentyp TTest, der die Werte A, B oder C annehmen kann. Nur wie mache ich das in JAVA?
Danke schon mal ;-)


PS: Noch ne kleine Frage: In Delphi/Pascal hat es sich eingebürgert für Klassen usw. den Großbuchstaben T vor den eigentlichen Namen zu schreieben (zur Unterscheidung eben..). Gibt es sowas in JAVA auch?


----------



## bygones (13. Okt 2004)

die Antwort hast du dir eigentlich schon gegeben  und die heißt Klassen *g (wie du die Klassen nennst ist dir überlassen - sie sollten mit Großbuchstaben beginnen und selbsprechend sein)....

Die Frage ist nun was für Datentypen A, B und C sind. wenn es z.b. ints sind kannst du ne Klasse haben:


```
public class TTest {
   private int a, b, c;
   
   public Test(int a, int b, int c) {
     this.a = a;
     this.b = b;
     this.c = c;
   }

   // methoden
}
```

wenn es nur darum geht versch. Werte unabhängig voneinander zu speichern reicht einen Collection (Vector / ArrayList)....


----------



## thE_29 (13. Okt 2004)

da sieht man das delphi nur reinklicken, bisi was schreiben, ohne selbst viel zu coden Sprach ist  ala vbasic 

aber wenns einem spass macht  (und es ist sicherlich leichter zu lernen )


----------



## Guest (13. Okt 2004)

thE_29 hat gesagt.:
			
		

> da sieht man das delphi nur reinklicken, bisi was schreiben, ohne selbst viel zu coden Sprach ist  ala vbasic
> 
> aber wenns einem spass macht  (und es ist sicherlich leichter zu lernen )


Auf so einen Mist habe ich gewartet... Delphi ist wesentlich besser Sprache als viele meinen. Und dieses "reinklicken" ist auch mist, das ist bei der Oberfläche so, mehr nicht! Und die GUI ist ja wohl ganz egal, gerade das ist der Vorteil von Delphi (und so schlecht scheint es ja nicht zu sein, wenn MS das nachmachen muss...).
Das andere ist genau so wie in jeder anderen Sprache... Sicherlich gibt es viele die meinen, nur weil ich ne Oberfläche zusammenklickern kann, kann ich programmieren. Es kann sein, dass die Anzahl immer größer wird, aber das ist nun mal nicht zu ändern... Ich gehöre da garantiert nicht zu.
Das Delphi neben diesem Vorteil noch einige andere hat, übersehen wie du auch ziemlich viele und mit VB ist das wirklich nicht zu vergleichen... Wer das meint ist selber schuld... :roll: 


@deathbyaclown: Nein, so war das nicht gemeint. Es sind keine INT's. A, B und C sind die Werte, die die Variabel annehmen kann. So etwas gibt es in C übrigens auch (@thE_29 ;-)).
Also ich will folgendes dann machen können:


> MeinTyp testvar = A; oder MeinTyp testvar = B; oder MeinTyp testvar = C;


Das würde mir einiges erleichtern. Kann sein, dass man es in einer Klasse in JAVA löst, ka.


----------



## Guest (13. Okt 2004)

Nachtrag: Es sind auch keien Char's oder String. Könnte ich zwar nehmen, aber das ganze wäre ziemlich bescheuert...


----------



## thE_29 (13. Okt 2004)

hehe 

hoffentlich habe ich dich in rage gebracht und ja, ich habe dieses vorurteil weil bei uns die gymnasien delphi "lernen" und dann sagen sie sind "programmierer" nur machen die nicht wirklich etwas selber

einfach klick und when eingabe then mache das und dann klick hier....

programmieren ist nicht nur doof zeilen reintippen, du musst es verstehen, wann wie etwas an die reihe kommt, usw (super in C mit message map..)

und was soll das heißen?

MeinTyp testvar = A;

das geht einfach nie und wird nie gehen! was ist A? ne Variable, ein Typ, ein Wert??

du weißt ja egientlich nicht mal genau wieviele Klassen dein Delphi programm erstellt wenn du

TTest  = (A,B,C)

(wenn das T aber für Templates steht, könnte das mit A,B,C eher sinn machen, aber du sagst es steht für Klasse - was i net wirklich glaube.. wie kommt von K/C auf T??!?)

außerdem würd mich das stark wundern wenn das in C geht, habe nämlich C/C++ gelernt, und so einen schmarn noch nie gesehen!

außer A, B, C sind variable oder define´s


----------



## Guest (13. Okt 2004)

Hallo,
OK, ich gebe dir recht (habe ich ja oben auch schon geschrieben...), das viele so denken.

Also noch mal.


> und was soll das heißen?
> 
> MeinTyp testvar = A;
> 
> das geht einfach nie und wird nie gehen! was ist A? ne Variable, ein Typ, ein Wert??


A ist keine Variabel, sondern praktisch ein Wert.
Also in Delphi würde es gehen.
Da kann ich mir einen eigenen Datentyp erstellen, der bestimmte Werte (A, B, C) annehmen kann.
Selber kann ich kein C/C++, ich weiß aber das es auch dort geht.
Und Schmarn ist es nicht, im Gegenteil...
Ich glaube ich habe ja geschrieben, dass ich mir für mein Schulprojekt einen kleinen math. Parser schreiben will. Das ist ja im Prinzip nicht all zu schwer...
So nun erstelle ich mir einen Baum und trage dort alle Werte rein, es kann ja einmal ein Operator oder halt eine Zahl sein. Wenn ich nun für die Operatoren einen eigenen Typ erstellen kann, so sieht das alles wesentlich besser aus ;-)
Hintergrund: Ich kann sagen, in der Klasse TNode (oder wie auch immer sie heißt) gibt es 2 Konstruktoren, der eine nimmt einen Operator vom typ Operator und der andere eine Zahl (ob Float, Double oder Int ist ja erstmal käse...) an.
Wenn ich nun einen Datentyp Operator habe, der beispielsweise die Werte add, sub, mul, div annehmen kann, habe ich es einfach übersichtlicher...
Sollte das JAVA nicht können, dann bin ich echt noch enttäuschter von JAVA ... (;-))


----------



## Guest (13. Okt 2004)

Nachtrag: Man bereichnet die Dinger auch als Aufzählungstypen.


----------



## bygones (13. Okt 2004)

Anonymous hat gesagt.:
			
		

> Nachtrag: Man bereichnet die Dinger auch als Aufzählungstypen.


dann schau dir mal die Enums in Java an...

ansonsten kannst du (nahezu) alles in java machen eben durch geschicktes Klassendesign. Du bestimmst was für Members eine Klasse hat...


----------



## Gast (13. Okt 2004)

Hast du vielleicht einen Link für mich?
Habe nämlich in meinem "javabuch" nichts gefunden


----------



## Gast (13. Okt 2004)

Ich habe gerade mit einem anderen Delphianer gesprochen und er meinte auch, dass es das in JAVA nicht gäbe. Schweinerei... (nicht böse werden ;-))
Gibt es noch eine andere Möglichkeit, folgendes zu machen:
Angenommen ich habe einen Datentyp Farben, der die WErte Gelb, Rot Blau annehmen kann.
Nun will ich jeden einzelnen Wert abfragen (case of bzw in JAVA switch-Anweisung).
Das soll halt möglichst elegant werden...


----------



## Gast (13. Okt 2004)

Oh es scheint ab JAVA 1.5 zu gehen...
enum Faben = {Rot, Blau, Gelb};
So wollte ich es haben...
Tja jetzt muss ich mir das nur noch installieren... *grusel*


----------



## thE_29 (13. Okt 2004)

und frag mal deinen delphianer wie der code bitte in c/c++ ausschaut, weil den kann ich mir einfach net vorstellen 


naja, mit nem switch halt


```
switch(FarbTyp) //muss int sein!
{
   case 0: //nehmen wir an 0 = rot
    dosth();
   break;
   case 1:
    //...
}
```

aber ich glaube du meinst sowas in der art


```
Farbe farbe = null;
    Rot rot = new Rot();
    Blau blau = new Blau();
    farbe = rot;
    if(farbe instanceof Rot)
    {
      System.out.println("BIST DU ROT?");
      farbe.Print();
    }
    else if(farbe instanceof Blau)
    {
      System.out.println("BIST DU BLAU?");
      farbe.Print();;
    }


//KLassen

  public interface Farbe{
    public void Print();
  }

  public class Rot implements Farbe{
    public void Print()
    {
      System.out.println("JA, ICH BIN ROT!");
    }
  }

  public class Blau implements Farbe{
    public void Print()
    {
      System.out.println("JA, ICH BIN BLAU");
    }
  }
```

wobei du die Funktion print im interface weglassen kannst, hab sie nur rein damit du das lernen kannst


----------



## bygones (13. Okt 2004)

enums sind neue Features in JAva 5 - kann mir den link net merken - such mal bei google nach "Java ist eine Insel" - ich glaube die haben das schon neu drinnen...

wenn es um die wirklichen Farben geht, da gibt es die Klasse Color und die hat schon als Konstanten die einzelnen Farben:
z.b. 
	
	
	
	





```
Color myColor = getColorFromAnyWhere();
if(myColor == Color.RED) {
   // is rot
}
else if(myColor == Color.BLACK) {
   // is schwarz
}
...
```



> Hintergrund: Ich kann sagen, in der Klasse TNode (oder wie auch immer sie heißt) gibt es 2 Konstruktoren, der eine nimmt einen Operator vom typ Operator und der andere eine Zahl (ob Float, Double oder Int ist ja erstmal käse...) an.


warum sollte das nicht gehen... mach zwei Unterklassen per Vererbung, die von TNode erben, eine hält die Operatoren, die andere die zahlen... (als eine Möglichkeit)


----------



## bygones (13. Okt 2004)

thE_29 hat gesagt.:
			
		

> naja, mit nem switch halt
> 
> 
> ```
> ...


ab 1.5 dank der Enums muss es nimmer int sein   


			
				the_29 hat gesagt.:
			
		

> aber ich glaube du meinst sowas in der art
> ...


warum so kompliziert wenn es um Farben geht ?!


_edited by thE_29: na da hats was gehabt :bae:_


----------



## Guest (13. Okt 2004)

thE_29 hat gesagt.:
			
		

> und frag mal deinen delphianer wie der code bitte in c/c++ ausschaut, weil den kann ich mir einfach net vorstellen


Der kann kein C/C++ ;-)



> naja, mit nem switch halt
> 
> 
> ```
> ...


Das ist mir soweit klar ;-)

aber ich glaube du meinst sowas in der art


> ```
> Farbe farbe = null;
> Rot rot = new Rot();
> Blau blau = new Blau();
> ...


Schon eher, glaube ich :mrgreen:
Aber das geht ja mit enums viel einfacher ;-)

@deathbyaclown Ne, geht nicht um Farben. Das war nur mal wieder ein schlechtes Beispiel ;-). Dann hätte ich einfach mal in die Hilfe geschaut, wenn es dadrin steht ;-)

Danke nochmal an euch beiden  Habt mir mit enum sehr viel geholfen ;-)

Wenn ich soweit bin, stelle ich hier mal den Parser vor...


----------



## Guest (13. Okt 2004)

Ach so hier noch mal der vollständige funktionierende Code:

```
enum TestVar {A, B, C};
     TestVar tt;
     tt = TestVar.B;

     if (tt == TestVar.A) System.out.println("Juhu");

     switch (tt) {
       case A: System.out.println("A");
               break;
       case B: System.out.println("B");
               break;
       case C: System.out.println("C");
               break;
     }
```


----------



## Reality (13. Okt 2004)

@the_29: C/C++ kann das auch und ältere Java-Versionen ebenfalls. Man muss sich eben selbst ein "Enum" bauen.


```
public class Typ{
}

class Bla{
Typ A = new Typ();
Typ B = new Typ();
Typ C = new Typ();

Typ variable;

if(bla1){
variable = A;
}

else if(bla2){
variable = B;
}

usw.
}
```

Liebe Grüße
Reality


----------



## Illuvatar (13. Okt 2004)

Noch besser so:


```
public class MyEnum
{
 private MyEnum()
 {}
 public static MyEnum A = new MyEnum();
 public static MyEnum B = new MyEnum();
 public static MyEnum C = new MyEnum();
}
```


----------



## Guest (13. Okt 2004)

Typsicher könnte man es so hinkriegen. (typesafe singleton)
	
	
	
	





```
public final class TTest implements Comparable, Serializable
{
  private static final long serialVersionUID = 9159729746711424082L;

  public static final TTest A = new TTest("A", 0);
  public static final TTest B = new TTest("B", 1);
  public static final TTest C = new TTest("C", 2);

  private transient String displayName;
  private int intValue;

  private TTest(String displayName, int intValue)
  {
    this.displayName = displayName;
    this.intValue = intValue;
  }

  public int intValue()
  {
    return this.intValue;
  }

  public int hasCode()
  {
    return intValue;
  }

  public String toString()
  {
    return this.displayName;
  }

  public int compareTo(Object o)
  {
    return this.intValue - ((TTest)o).intValue;
  }

  protected Object readResolve() throws ObjectStreamException
  {
    switch(this.intValue)
    {
    case 0: return A;
    case 1: return B;
    case 3: return C;
    default: throw new InvalidObjectException("Unknown TTTest.intValue: "+ this.intValue);
    }
  }
}
...
...
TTest a = TTest.A;
TTest b = TTest.B;
TTest c = TTest.C;
```


----------



## Guest (13. Okt 2004)

Ehmm... :autsch:

```
protected Object readResolve() throws ObjectStreamException 
  { 
    switch(this.intValue) 
    { 
    case 0: return A; 
    case 1: return B; 
    case 2: return C; 
    default: throw new InvalidObjectException("Unknown TTTest.intValue: "+ this.intValue); 
    } 
  }
```


----------



## Alexander (13. Okt 2004)

Oh. Danke.
aber ich glaube ich belasse das erstma dabei.
Evtl. probier ich noch ein wenig rum.


----------



## Gast (13. Okt 2004)

Der Nachteil ist ja, wenn ich das so mache wie ihr das beschrieben habt, also einen Enum selber schreiben, dann klappt das ja nicht so schön mit dem switch.
Dann müsste ich das in einen Int umwandeln und dann hätte ich wieder nichtssagende Zahlen da stehen. Beim richtigen Enum (siehe oben, mein Posting) kann ich das im Switch wie oben richtig hinschreiben und jeder weiß, was gemeint war.
Daher finde ich die Lösung am besten.
Grüße, Alexander


----------



## Guest (13. Okt 2004)

Wenn JDK 1.5 gemeint ist, dann hast Du Recht.  :wink:


----------



## Reality (13. Okt 2004)

Illuvatar hat gesagt.:
			
		

> Noch besser so:
> 
> 
> ```
> ...



Was bringt eigentlich der private Konstruktor? Haben den Sinn vergessen...

Liebe Grüße
Reality


----------



## Illuvatar (13. Okt 2004)

Habe ich dir das nicht schonmal erklärt, Reality?
Damit es nicht mehr als diese drei Instanzen gibt.

Noch korrekter wäre übrigens:

```
public final class MyEnum 
{ 
  private MyEnum() 
  {} 
  public static MyEnum A = new MyEnum(); 
  public static MyEnum B = new MyEnum(); 
  public static MyEnum C = new MyEnum(); 
}
```


----------



## Bleiglanz (14. Okt 2004)

der switch geht in der 1.5.er, wenn man mit dem typesafe-enum-pattern sowas machen will, dann einfach als member hinzufügen

```
public final class MyEnum
{
  final public int ordinal;
  private MyEnum(int newOrdinal)
  {
      this.ordinal = newOrdinal;
  }
  public static MyEnum A = new MyEnum(1);
  public static MyEnum B = new MyEnum(2);
  public static MyEnum C = new MyEnum(3);
}
//
//    dann case MyEnum.A.ordinal: ...; break;
//            case MyEnum.B.ordinal: ...; break;
//
```


----------



## thE_29 (14. Okt 2004)

nur so ne Frage, aber wo isn der Unterschied zwischen den 3en?


```
public static MyEnum A = new MyEnum();
  public static MyEnum B = new MyEnum();
  public static MyEnum C = new MyEnum();
```

werden ja alle mit dem gleichen Kontruktor aufgerufen nur heißen sie von A - C nur unterschiedlich sind die net!

und das bsp was Gast mit enum gepostet hat, ist ein gewaltiger unterschied zwischen euren!
ihr habt einfach 3 variablen die 1: 1 das gleiche sind! nur anders heißen.....

enum ist was anders (in C und in Java 1.5 auch )


----------



## bygones (14. Okt 2004)

thE_29 hat gesagt.:
			
		

> gepostet hat, ist ein gewaltiger unterschied zwischen euren!
> ihr habt einfach 3 variablen die 1: 1 das gleiche sind! nur anders heißen.....


nein sie sind nicht 1:1 gleich. es sind drei verschiedenen instanzen... die benennung ist nicht glücklich, aber wenn du dir sie als Montag, Dienstag usw. vorstellst wird es einfacher zu verstehen... Enums in 1.5 sind natürlich mächtiger, da sie noch ein eigenes Verhalten haben können....


----------



## thE_29 (14. Okt 2004)

jo, sie sind nicht 1:1 gleich, aber wenn du etwas machst mit einer integer abfrage (also die initvalue) ob es nun montag dienstag mittwoch ist, wäre es geschickter wenn du ein interface machen würdest


```
public interface Wochentag{
}

public class Montag extends Wochentag{
}
public class Dienstag extends Wochentag{
}
//.......

Wochentag tag = getDayBack(); //liefert entweder Montag,....
if(tag instanceof Montag)
  System.out.println("Montag");
```

sowas ist sicherlich besser als etwas über int zu lösen

am besten wäre es halt mit enum


----------



## Bleiglanz (14. Okt 2004)

der witz bei den Enums ist ja, dass man weder equals noch instanceof wirklich braucht, weil (readresolve vorausgesetzt) der == Operator das richtige macht


```
MyEnum var = fooMethod();
if(var == MyEnum.A) {
}
```

usw.

_edit deathbyaclown: code tags_


----------



## thE_29 (14. Okt 2004)

jo, das ist ja das sinnvolle bei enums, ansonsten wären sie ja sinnlos, wenn du wieder was mit instanceof oder mit einem integer wert abfragen musst


----------



## Alexander (14. Okt 2004)

Genau so sehe ich das auch. Enums sind da besser. 
Anders wäre das müll und hätte nicht wirklihc ein Vorteil.
Ich möchte auch den Switch benutzen, da ich tausende IF-Bedingungen für schwachfug halte (und bei mir würde das darauf hinauslaufen da ich zig Operatoren abfragen muss...)
Grüße, Alexander


----------



## bygones (14. Okt 2004)

thE_29 hat gesagt.:
			
		

> jo, sie sind nicht 1:1 gleich, aber wenn du etwas machst mit einer integer abfrage (also die initvalue) ob es nun montag dienstag mittwoch ist, wäre es geschickter wenn du ein interface machen würdest
> 
> ```
> public interface Wochentag{
> ...


Ja ABER !!!

Mit den "glorified integers" wäre auch das um einiges einfacher... bsp wochentage:

```
final class Wochentage {
 private Wochentage() {
 }

 public static final Wochentage MONTAG = new Wochentage();
 public static final Wochentage DIENSTAG = new Wochentage();
 .....
}

public class TestClass {
  Wochentage w;

  public TestClass(Wochentage w) {
     this.w = w;
  }

  public Wochentage getDay() {
   return w;
  }

  public static void main(String[] args) {
    TestClass t = new TestClass(Wochentage.MONTAG);
    if(t.getDay() == Wochentage.MONTAG) {
     System.out.println("is a Montag");
   }
}
```
halte ich für einfache v.a. wegen weniger Klassen !!

_ na da war noch ein code tag :bae:_


----------



## thE_29 (14. Okt 2004)

jo, das könntest mit defines in c genau so lösen 

deswegen gibts halt die enums, das du auf sowas nicht zurückgreifen musst!

aber eine super idee


----------



## Reality (14. Okt 2004)

Illuvatar hat gesagt.:
			
		

> Habe ich dir das nicht schonmal erklärt, Reality?
> Damit es nicht mehr als diese drei Instanzen gibt.
> 
> Noch korrekter wäre übrigens:
> ...


Ja, hatte ich wieder vergessen. :bae:
Danke.


----------



## Gast (16. Okt 2004)

Hallo,
ich habe noch mal eine Frage zu den Enums. Und zwar kann irgendwie herausfinden, wieviele solcher Aufzählungstypen in einem Enum sind?
Bei enum TTest {A, B, C} wären es ja drei bzw. zwei, wenn man bei 0 anfängt...
Wäre cool, wenn ihr mir da noch mal weiterhelfen könntet...


----------



## Gast (16. Okt 2004)

Und noch eine Frage, gibt es eine Möglichkeit diese dann auch mit einer Schleife ähnlich eines Arrays durchzugehen?


----------



## bygones (16. Okt 2004)

schau dir die Klasse EnumSet an.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html#allOf(java.lang.Class)
damit bekommst du alle enum elemente in das set

und das es iteratable ist kannst du über die neue forschleife durchlaugen


----------



## Gast (17. Okt 2004)

Danke, werde es mir nachher mal anschaun 
Bei Fragen melde ich mich noch mal ....


----------

