Inselupdate: enum mit eigenen Konstruktoren und Methoden

Da eine enum-Klasse mit der Klassendeklaration verwandt ist, kann sie ebenso Attribute und Metho-den deklarieren. Geben wir einer Aufzählung Country eine Methode, die den ISO 3166-2 Landescode des jeweiligen Aufzählungselements liefert:

public enum Country
{
  GERMANY, UK, CHINA;

  public String getISO3Country()
  {
    if ( this == GERMANY )
      return Locale.GERMANY.getISO3Country();
    else if ( this == UK )
      return Locale.UK.getISO3Country();
    return Locale.CHINA.getISO3Country();
  }
}   

Die Methode getISO3Country() kann nun auf den Enum-Objekten aufgerufen werden.

System.out.println( Country.CHINA.getISO3Country() ); // CHN
Da switch auf enum erlaubt ist, können wir schreiben:

Country c = Country.GERMANY;

switch ( c )
{
  case GERMANY:
    System.out.println( "Aha. Ein Krauti" );         // Aha. Ein Krauti
    System.out.println( meinLand.getISO3Country() ); // DEU
    break;
  default:      System.out.println( "Anderes Land" );
}

Enum mit Konstruktoren

Neben dieser Variante wollen wir eine zweite Implementierung nutzen, und nun Konstruktoren hinzu-ziehen, um das gleiche Problem auf andere Weise zu lösen:

public enum Country
{
  GERMANY( Locale.GERMANY ), UK( Locale.UK ), CHINA( Locale.CHINA );

  private Locale country;

  private Country( Locale country )
  {
    this.country = country;
  }

  public String getISO3Country()
  {
    return country.getISO3Country();
  }
}

Bei der Deklaration der Konstanten wird in runden Klammern ein Argument für den Konstruktor übergeben. Der Konstruktor speichert das zugehörige Locale-Objekt in der internen Variable country, auf die dann getISO3Country() Bezug nimmt.

Enum mit überschriebenen Methoden   

In dem Enum-Typen lassen sich nicht nur Methoden hinzufügen, sondern auch Methoden überschrei-ben. Beginnen wir mit einer lokalisierten und überladenen Methode toString().

public enum WeekdayInternational
{
  SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

  @Override
  public String toString()
  {
    return new SimpleDateFormat().getDateFormatSymbols().getWeekdays()[ ordinal() + 1 ]; 
  }

  public String toString( Locale l )
  {
    return new SimpleDateFormat("", l).getDateFormatSymbols().getWeekdays()[ ordinal() + 1 ]; 
  }
}

Die erste Methode ist aus unserer Oberklasse Object überschrieben, die zweite als überladene Funk-tion hinzugefügt. Ein Beispiel macht den Aufruf und die Funktionsweise klar:

System.out.println( WeekdayInternational.SATURDAY );                         // Samstag
System.out.println( WeekdayInternational.SATURDAY.toString() );              // Samstag
System.out.println( WeekdayInternational.SATURDAY.toString(Locale.FRANCE) ); // samedi
System.out.println( WeekdayInternational.SATURDAY.toString(Locale.ITALY) );  // sabato

An dieser Stelle hören die Möglichkeiten der Enum-Syntax aber noch nicht auf. Ähnlich wie die Syn-tax von inneren anonymen Klassen, die es erlauben, Methoden zu überschreiben, bieten Aufzählungs-typen eine ähnliche Syntax, um gezielt Methoden für eine spezielle Konstante zu überschreiben.

Nehmen wir an, in einem Spiel gibt es eine eigene Währung, denn Ponro Dollar. Nun soll dieser aber mit einer Referenzwährung, dem Euro, in Beziehung gesetzt werden: Der Wechselkurs ist einfach 1:2.

public enum GameCurrency
{
  EURO() {
    @Override double convertTo( GameCurrency targetCurrency, double value )
    {
      return targetCurrency == EURO ? value : value / 2;
    }
  },
  PONRODOLLAR() {
    @Override double convertTo( GameCurrency targetCurrency, double value )
    {
      return targetCurrency == PONRODOLLAR ? value : value * 2;
    }
  }; 
  abstract double convertTo( GameCurrency targetCurrency, double value );
}

Der interessante Teil ist die Deklaration der abstrakten convertTo() Methode und der Implementie-rung lokal bei den einzelnen Konstanten. (Natürlich müssen wir nicht jede Methoden im Enum abs-trakt machen, sondern sie kann auch konkret sein. Dann muss nicht jedes Enum-Element die abstrakte Methode implementieren.)

Mit einem statischen Import für die Aufzählung lässt sich die Nutzung und Funktionalität schnell zeigen:

System.out.println( EURO.convertTo( EURO, 12 ) );               // 12.0
System.out.println( EURO.convertTo( PONRODOLLAR, 12 ) );        // 6.0
System.out.println( PONRODOLLAR.convertTo( EURO, 12 ) );        // 24.0
System.out.println( PONRODOLLAR.convertTo( PONRODOLLAR, 12 ) ); // 12.0

Labels:

0 Antwort(en) auf ›Inselupdate: enum mit eigenen Konstruktoren und Methoden‹

Kommentar veröffentlichen