Enums in Java erweitern

Sheeraz Gul 12 Oktober 2023
Enums in Java erweitern

Dieses Tutorial zeigt, wie man die enum-Funktionalität in Java erweitert.

Erweitern Sie enum in Java

Wir können enum als eine Art Compiler-Magie betrachten, denn im byte-Code wird das enum als Klasse mit mehreren statischen Membern dargestellt und vom abstrakten java.lang.Enum geerbt.

Aus diesem Grund kann das enum keine andere Klasse oder enum erweitern. Da wir enum in Java nicht erweitern können, ist es auch für keine Klasse möglich, ein enum zu erweitern. Lassen Sie uns anhand des folgenden Beispielcodes lernen und sehen, was passiert.

Beispielcode:

package delftstack;

enum Cars { Audi, BMW, Marcedes }

public class Example extends Cars {
  public static void main(String... args) {}
}

Der obige Code hat ein enum namens Cars, und die Klasse Example versucht, es zu erweitern. Siehe Ausgabe:

/Example.java:5: error: cannot inherit from final Cars
public class Example extends Cars {
                             ^
/Example.java:5: error: enum types are not extensible
public class Example extends Cars {
       ^
2 errors

Wie wir sehen können, kann die Klasse das enum nicht erweitern. Wenn es also unmöglich ist, das enum zu erweitern, können wir seine Funktionalität trotzdem erweitern?

Die Funktionalität kann als implementierte Methode im enum definiert werden. Zum Beispiel kann das enum Cars aus dem obigen Code abstrakte Methoden für jedes Member deklarieren; siehe Beispiel:

enum Cars {
  Audi {
    @Override
    public void drive() {}
  },
  BMW {
    @Override
    public void drive() {}
  },
  Mercedes {
    @Override
    public void drive() {}
  },
  ;
  public abstract void drive();
}

Wie wir sehen können, kann jedes Mitglied die Methode drive() überschreiben. Aber leider ist es nicht immer möglich, Methoden in enum zu erstellen, weil:

  • Wenn das enum zu einer Bibliothek eines Drittanbieters oder einem anderen Team gehört, erlaubt es keine Implementierung abstrakter Methoden.
  • Wenn es zu dem Modul gehört, das nicht die für die Methode drive() erforderliche Abhängigkeit hat.
  • Wenn das enum mit anderen Funktionen und Daten überladen ist, wird es unlesbar.

Es werden einige Lösungen bereitgestellt, die diese Probleme lösen und die Funktionalität von enum in Java erweitern können.

Lösung 1: Mirror enum in Java

Wie der Name schon sagt, müssen wir ein weiteres enum mit denselben Daten erstellen. Dieses neue enum wird auch die drive()-Methode implementieren, also haben wir jetzt zwei enums:

Beispielcode für enum Cars:

enum Cars {
  Audi {
    @Override
    public void drive() {}
  },
  BMW {
    @Override
    public void drive() {}
  },
  Mercedes {
    @Override
    public void drive() {}
  },
  ;
  public abstract void drive();
}

Beispielcode für enum DriveCars:

enum DriveCars {
  Audi {
    @Override
    public void drive() {}
  },
  BMW {
    @Override
    public void drive() {}
  },
  Mercedes {
    @Override
    public void drive() {}
  },
  ;
  public abstract void drive();
}

Das zweite enum ist der Spiegel des ersten. Jetzt können wir diese beiden Aufzählungen verwenden, indem wir die Funktionalität erweitern; wir müssen eingebaute enum-Methoden verwenden, nämlich name() und valueof().

Sehen Sie sich das folgende Beispiel zur Verwendung an:

Cars cars = ... DriveCars.valueOf(cars.name()).drive();

Der obige Code zeigt, wie die enum Cars-Funktionalität in den enum DriveCars verwendet wird. Das heißt, die Funktionalität wird erweitert.

Die Methode name() im obigen Code ist final, was nicht überschrieben werden kann, und die Methode valueOf wird vom Compiler generiert. Beide Verfahren passen gut zusammen, wenn im erweiterten Betrieb kein Funktionsfehler auftritt.

Es gibt ein Problem mit dem obigen Code, wenn enum Cars geändert wird, hat das enum DriveCars keine Ahnung, und es führt zum Scheitern des name- und valueof-Tricks. Um dieses Problem zu lösen, müssen wir DriveCars mitteilen, dass sein Elternspiegel Cars ist.

Dafür können wir einen statischen Initialisierer verwenden, um DriveCars und Cars zu vergleichen, der die Ausnahme auslöst, wenn beide Aufzählungen nicht übereinstimmen. Hier ist ein Beispiel dafür aus der enumus-Bibliothek:

enum DriveCars {
  ....static { Mirror.of(Cars.class); }
}

Die Utility-Klasse prüft, ob beide Aufzählungen übereinstimmen oder nicht. Diese Methode validiert den name()- und valueOf()-Trick.

Lösung 2: Map enum in Java

Wenn Sie kein weiteres enum erstellen möchten, das nur eine Methode enthält. In diesem Fall können wir statt enum interface verwenden; siehe das Beispiel unten:

public interface Driver {
  void drive();
}

Um nun diese Schnittstelle Drive mit den enum Cars zu verwenden, können wir eine Zuordnung zwischen ihnen erstellen. Hier ist das Beispiel für die Karte:

Map<Cars, Driver> drivers = new EnumMap<>(Cars.class) {
  {
    put(Audi, new Driver() {
      @Override
      public void driver() {}
    }) put(BMW, new Driver() {
      @Override
      public void driver() {}
    }) put(Mercedes, new Driver() {
      @Override
      public void driver() {}
    })
  }
}

Um sie jetzt zu verwenden, verwenden Sie diesen einfachen Code:

drivers.get(Cars).drive();

Die im obigen Code verwendete EnumMap garantiert, dass jedes enum-Mitglied nur einmal auftaucht, garantiert aber keinen Eintrag für jedes Mitglied.

Wir können überprüfen, ob die Größe der Karte der Anzahl der Mitglieder von Aufzählungen entspricht:

drivers.size() == Cars.values().length

Auch für diesen Fall bietet die Bibliothek enumus ein Hilfsmittel: Passt die Karte nicht zu den Cars, wirft sie die IllegalStateException. Hier ist das Dienstprogramm:

EnumMapValidator.validateValues(Cars.class, map, "Cars map");

Beide obigen Methoden zeigen, wie Sie Aufzählungen durch Erweitern ihrer Funktionalität leistungsfähig machen können. Obwohl es unmöglich ist, ein enum direkt zu erweitern, können wir diese Tricks verwenden, um ihre Funktionalitäten zu erweitern.

Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook

Verwandter Artikel - Java Enum