Menu
Coddy logo textTech

Konstruktoren & Vererbung

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 41 von 110.

Wenn eine Unterklasse eine Basisklasse erweitert, muss der Konstruktor der Basisklasse aufgerufen werden, um geerbte Felder ordnungsgemäß zu initialisieren. Dart bietet flexible Möglichkeiten, dies über die Initialisierungsliste unter Verwendung von super zu handhaben.

Wenn die Elternklasse einen parametrisierten Konstruktor hat, muss die Kindklasse diesen explizit aufrufen:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
}

class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
}

Dart 2.17 führte Super-Parameter ein, eine sauberere Syntax, die Parameter direkt an den Konstruktor der Elternklasse weiterleitet:

class Student extends Person {
  String school;
  
  // super.name und super.age werden direkt an den Konstruktor von Person weitergeleitet
  Student(super.name, super.age, this.school);
}

Wenn Sie mit benannten Konstruktoren arbeiten, geben Sie an, welcher Konstruktor der Elternklasse aufgerufen werden soll:

class Employee extends Person {
  String department;
  
  Employee(super.name, super.age, this.department);
  
  Employee.intern(String name, this.department) : super(name, 18);
}

Die Grundregel ist einfach: Die Elternklasse muss vollständig initialisiert sein, bevor die Kindklasse ihre eigenen Eigenschaften hinzufügt. Ob Sie den traditionellen super()-Aufruf oder die neueren Super-Parameter verwenden, Dart stellt sicher, dass die Vererbungskette ordnungsgemäß von der Eltern- zur Kindklasse aufgebaut wird.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Produktinventarsystem erstellen, das zeigt, wie Konstruktoren mit Vererbung funktionieren. Sie werden eine Hierarchie erstellen, in der verschiedene Produkttypen eine Basis-Produktklasse erweitern, wobei jeder Typ eine ordnungsgemäße Initialisierung durch Eltern-Konstruktoren erfordert.

Sie werden Ihren Code in zwei Dateien organisieren:

  • product.dart: Definieren Sie hier Ihre Produkthierarchie:
    • Eine Product-Klasse mit den Eigenschaften String name und double price, einem Konstruktor, der beide Werte entgegennimmt, und einer Methode info(), die [name]: $[price] ausgibt
    • Eine Book-Klasse, die Product erweitert und eine String author-Eigenschaft hinzufügt. Verwenden Sie Super-Parameter, um name und price an den Eltern-Konstruktor weiterzuleiten
    • Eine Electronics-Klasse, die Product erweitert und eine int warranty-Eigenschaft (in Monaten) hinzufügt. Verwenden Sie den traditionellen super()-Aufruf in der Initialisierungsliste, um Werte an das Elternteil zu übergeben
  • main.dart: Importieren Sie Ihre Produktdatei und demonstrieren Sie beide Ansätze der Konstruktor-Vererbung:
    • Erstellen Sie ein Book mit dem Namen 'Dart Essentials', dem Preis 29.99 und dem Autor 'Jane Smith'
    • Rufen Sie dessen info()-Methode auf und geben Sie dann Author: [author] aus
    • Geben Sie eine Leerzeile aus
    • Erstellen Sie ein Electronics-Objekt mit dem Namen 'Wireless Mouse', dem Preis 45.50 und der Garantie 24
    • Rufen Sie dessen info()-Methode auf und geben Sie dann Warranty: [warranty] months aus

Beide Kindklassen erben die info()-Methode von Product, ohne sie überschreiben zu müssen. Der Hauptunterschied liegt darin, wie sie den Eltern-Konstruktor aufrufen – Book verwendet die sauberere Super-Parameter-Syntax, während Electronics den traditionellen Ansatz mit super() in der Initialisierungsliste nutzt.

Erwartete Ausgabe:

Dart Essentials: $29.99
Author: Jane Smith

Wireless Mouse: $45.5
Warranty: 24 months

Spickzettel

Wenn eine Kindklasse eine Elternklasse erweitert, muss der Konstruktor der Elternklasse aufgerufen werden, um die geerbten Felder ordnungsgemäß zu initialisieren.

Traditioneller Ansatz – expliziter Aufruf des Elternkonstruktors in der Initialisierungsliste:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
}

class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
}

Super-Parameter (Dart 2.17+) – Parameter direkt an den Elternkonstruktor weiterleiten:

class Student extends Person {
  String school;
  
  Student(super.name, super.age, this.school);
}

Benannte Konstruktoren – angeben, welcher Elternkonstruktor aufgerufen werden soll:

class Employee extends Person {
  String department;
  
  Employee(super.name, super.age, this.department);
  
  Employee.intern(String name, this.department) : super(name, 18);
}

Probier es selbst

import 'product.dart';

void main() {
  // TODO: Erstelle ein Book mit:
  // - name: 'Dart Essentials'
  // - price: 29.99
  // - author: 'Jane Smith'

  // TODO: Rufe die Methode info() des Buchs auf

  // TODO: Gib "Author: [author]" aus

  // TODO: Gib eine Leerzeile aus

  // TODO: Erstelle ein Electronics mit:
  // - name: 'Wireless Mouse'
  // - price: 45.50
  // - warranty: 24

  // TODO: Rufe die Methode info() der Elektronik auf

  // TODO: Gib "Warranty: [warranty] months" aus
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung