Aufzählungen

Ein Aufzählungstyp ist eine spezielle Klasse, mit der sich eine festgelegte Menge konstanter Werte darstellen lässt.

Jede Aufzählung erbt automatisch von der Klasse Enum. Gleichzeitig handelt es sich bei Aufzählungen um versiegelte Typen (sealed): Sie können nicht vererbt, implementiert, eingeblendet oder manuell explizit instanziiert werden.

Abstrakte Klassen und Mixins können explizit Enum erben oder implementieren. Solange diese Klassen oder Mixins aber nicht durch eine Aufzählung deklariert oder eingebunden werden, lassen sich keine konkreten Objekte davon erstellen.

Verwenden Sie das Schlüsselwort enum und listen Sie alle Aufzählungskonstanten auf, um eine einfache Aufzählung zu definieren:

enum Color { red, green, blue }

Bei der Deklaration einer Aufzählung ist ein nachgestelltes Komma erlaubt. Das vereinfacht Kopieren und Einfügen und reduziert Codefehler.

Erweiterte Aufzählungen (Enhanced enums)

Dart unterstützt erweiterte Aufzählungen. Darin lassen sich wie bei normalen Klassen Memberfelder, Methoden und konstante Konstruktoren definieren – Instanzen dürfen aber nur die vordefinierten festen Konstanten sein.

Für die Deklaration einer erweiterten Aufzählung gelten zwingende Regeln:

  1. Instanzvariablen müssen als final gekennzeichnet sein (auch Variablen aus eingebundenen Mixins)
  2. Sämtliche generierenden Konstruktoren müssen mit const markiert werden
  3. Fabrikkonstruktoren dürfen nur bereits innerhalb der Aufzählung definierte Konstanteninstanzen zurückgeben
  4. Eine explizite Vererbung von weiteren Klassen ist nicht möglich (die Vererbung von Enum erfolgt automatisch)
  5. Es ist verboten, index, hashCode sowie den Gleichheitsoperator == zu überschreiben
  6. In einer Aufzählung darf kein Member mit dem Namen values angelegt werden. Dies würde mit dem automatisch generierten statischen Accessor values kollidieren
  7. Alle Instanzen der Aufzählung müssen ganz am Anfang der Definition stehen, mindestens eine Instanz ist erforderlich
  8. In Instanzmethoden einer erweiterten Aufzählung können Sie über this auf die aktuelle Aufzählungskonstante verweisen

Beispiel

enum Vehicle implements Comparable<Vehicle> {
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  final int tires;
  final int passengers;
  final int carbonPerKilometer;

  // Getter
  int get carbonFootprint => (carbonPerKilometer / passengers).round();
  bool get isTwoWheeled => this == Vehicle.bicycle;

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}Code language: Dart (dart)

Ab Dart 3.13 vereinfachen Hauptkonstruktoren die Schreibweise erweiterter Aufzählungen:

enum Vehicle(
  final int tires,
  final int passengers,
  final int carbonPerKilometer,
) implements Comparable<Vehicle> {
  car(4, 5, 400),
  bus(6, 50, 800),
  bicycle(2, 1, 0);

  int get carbonFootprint => (carbonPerKilometer / passengers).round();
  bool get isTwoWheeled => this == Vehicle.bicycle;

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}Code language: Dart (dart)

Verwenden von Aufzählungen

Der Zugriff auf Aufzählungskonstanten funktioniert wie bei statischen Variablen:

final favoriteColor = Color.blue;
if (favoriteColor == Color.blue) {
  print('Deine Lieblingsfarbe ist blau!');
}Code language: Dart (dart)

Eigenschaft index

Jede Aufzählungskonstante verfügt über die Eigenschaft index. Diese gibt die von Null beginnende Ordnungsnummer innerhalb der Aufzählungsdefinition zurück:

assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);Code language: Dart (dart)

Statische Konstante values

Rufen Sie über Aufzählungsname.values eine Liste mit allen Werten der Aufzählung ab:

List<Color> colors = Color.values;
assert(colors[2] == Color.blue);Code language: Dart (dart)

Aufzählungen mit switch kombinieren

Wenn Sie eine Aufzählung in einem switch verwenden, gibt der Compiler eine Warnung aus, falls nicht alle Zweige abgedeckt sind. Mit default können Sie übrige Fälle auffangen.

var aColor = Color.blue;

switch (aColor) {
  case Color.red:
    print('Rot wie Rosen!');
  case Color.green:
    print('Grün wie Gras!');
  default:
    print(aColor); // Color.blue
}Code language: Dart (dart)

Eigenschaft name

Rufen Sie über .name den passenden Zeichenfolgennamen einer Aufzählungskonstante ab:

print(Color.blue.name); // Gibt "blue" ausCode language: Dart (dart)

Zugriff auf benutzerdefinierte Member der Aufzählung

Bei erweiterten Aufzählungen greifen Sie auf selbst definierte Felder, Getter und Methoden wie bei normalen Objekten zu:

print(Vehicle.car.carbonFootprint);Code language: CSS (css)

Hier sehen Sie ein vollständiges Beispiel aus dieser Lektion. Wir erstellen eine Aufzählung für Monate und wenden alle gelernten Konzepte an.

enum Month implements Comparable<Month> {
  january(1, '一月', days: 31),
  february(2, '二月', days: 28),
  march(3, '三月', days: 31),
  april(4, '四月', days: 30),
  may(5, '五月', days: 31),
  june(6, '六月', days: 30),
  july(7, '七月', days: 31),
  august(8, '八月', days: 31),
  september(9, '九月', days: 30),
  october(10, '十月', days: 31),
  november(11, '十一月', days: 30),
  december(12, '十二月', days: 31);

  const Month(this.monthNumber, this.cnName, {required this.days});

  /// Nummer des gregorianischen Monats von 1 bis 12
  final int monthNumber;

  /// Name
  final String cnName;

  /// Tage im Normaljahr
  final int days;

  /// Getter: Gehört zum ersten Quartal?
  bool get isFirstQuarter => monthNumber <= 3;

  /// Getter: Hat 31 Tage?
  bool get has31Days => days == 31;

  /// Benutzerdefinierte Methode: Prüft, ob Februar eines Schaltjahrs vorliegt
  bool isLeapYearFebruary(int year) {
    if (this != Month.february) return false;
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  }

  /// Implementiert Comparable zum Sortieren
  @override
  int compareTo(Month other) {
    return monthNumber - other.monthNumber;
  }
}

void main() {
  // 1. Einfacher Zugriff auf Aufzählungskonstanten
  Month current = Month.august;
  print('Aktuelle Aufzählung: $current');
  print('name-Eigenschaft der Aufzählung: ${current.name}');
  print('Monat: ${current.cnName}');
  print('Monatsnummer 1~12: ${current.monthNumber}');
  print('Tage im Normaljahr: ${current.days}');
  print('Monat mit 31 Tagen? ${current.has31Days}');
  print('Gehört zum ersten Quartal? ${current.isFirstQuarter}');

  // 2. Eigenschaft index (Indexreihenfolge bei Definition, beginnt bei 0)
  print('\n${Month.january.name} index = ${Month.january.index}');
  print('${Month.december.name} index = ${Month.december.index}');

  // 3. values zum Abrufen der vollständigen Monatsliste
  List<Month> allMonths = Month.values;
  print('\nEs gibt insgesamt ${allMonths.length} Monate');

  // 4. switch mit Aufzählung nutzen
  print('\n==== switch-Auswertung ====');
  switch (current) {
    case Month.january:
      print('Beginn des Jahres');
    case Month.february:
      print('Kann einen Schalttag enthalten');
    case Month.march:
    case Month.april:
    case Month.may:
      print('Frühjahr');
    case Month.june:
    case Month.july:
    case Month.august:
      print('Sommer');
    case Month.september:
    case Month.october:
    case Month.november:
      print('Herbst');
    case Month.december:
      print('Winter, Jahresende');
  }

  // 5. Aufruf der benutzerdefinierten Methode
  Month feb = Month.february;
  print('\nIst Februar 2024 ein Schaltmonat? ${feb.isLeapYearFebruary(2024)}');
  print('Ist Februar 2025 ein Schaltmonat? ${feb.isLeapYearFebruary(2025)}');

  // 6. Sortieren von Aufzählungen (mittels Comparable-Schnittstelle)
  var selected = [Month.october, Month.january, Month.july];
  selected.sort();
  print('\nSortierte Monate: ${selected.map((m) => m.cnName).toList()}');
}Code language: Dart (dart)

Ausgabeergebnis

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Aktuelle Aufzählung: Month.august
name-Eigenschaft der Aufzählung: august
Monat: 八月
Monatsnummer 1~12: 8
Tage im Normaljahr: 31
Monat mit 31 Tagen? true
Gehört zum ersten Quartal? false

january index = 0
december index = 11

Es gibt insgesamt 12 Monate

==== switch-Auswertung ====
Sommer

Ist Februar 2024 ein Schaltmonat? true
Ist Februar 2025 ein Schaltmonat? false

Sortierte Monate: [一月, 七月, 十月]Code language: JavaScript (javascript)

Aufzählungen

Previous:

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *