Menu
Coddy logo textTech

Polymorphismus-Grundlagen

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

Polymorphismus bedeutet „viele Formen“ – es ist die Fähigkeit, Objekte verschiedener Klassen über eine gemeinsame Schnittstelle zu behandeln. Wenn Sie eine Referenz einer Elternklasse haben, kann diese auf jedes Objekt einer Kindklasse verweisen, und die korrekte Methode wird basierend auf dem tatsächlichen Objekttyp aufgerufen.

Das ist leistungsstark, da Sie Code schreiben können, der mit dem Elterntyp arbeitet und dennoch automatisch alle Kindtypen korrekt verarbeitet:

class Animal {
  void speak() => print('Some sound');
}

class Dog extends Animal {
  @override
  void speak() => print('Woof!');
}

class Cat extends Animal {
  @override
  void speak() => print('Meow!');
}

void main() {
  Animal myPet = Dog();  // Elterntyp, Kindobjekt
  myPet.speak();  // Ausgabe: Woof!
  
  myPet = Cat();  // Dieselbe Variable, anderes Objekt
  myPet.speak();  // Ausgabe: Meow!
}

Die Variable myPet ist als Animal deklariert, aber sie enthält ein Dog oder Cat. Wenn speak() aufgerufen wird, schaut Dart zur Laufzeit auf den tatsächlichen Objekttyp und ruft die entsprechende überschriebene Methode auf.

Dies ermöglicht es Ihnen, flexible Funktionen zu schreiben, die mit jeder Unterklasse funktionieren:

void makeAllSpeak(List<Animal> animals) {
  for (var animal in animals) {
    animal.speak();  // Jedes Tier spricht auf seine eigene Weise
  }
}

void main() {
  var pets = [Dog(), Cat(), Dog()];
  makeAllSpeak(pets);
  // Ausgabe: Woof! Meow! Woof!
}

Die Funktion muss nichts über Dog oder Cat wissen – sie arbeitet einfach mit Animal. Dies macht Ihren Code erweiterbarer, da das Hinzufügen neuer Tierarten keine Änderungen an bestehenden Funktionen erfordert.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Musikinstrumentensystem bauen, das Polymorphismus in Aktion demonstriert. Sie erstellen eine Basisklasse Instrument und verschiedene Instrumententypen und schreiben dann eine Funktion, die jede Sammlung von Instrumenten zusammen spielen lassen kann - ohne deren spezifische Typen zu kennen.

Sie werden Ihren Code in zwei Dateien organisieren:

  • instruments.dart: Definieren Sie hier Ihre Instrumentenhierarchie:
    • Eine Instrument-Klasse mit einer String name-Eigenschaft und einem Konstruktor. Fügen Sie eine Methode play() hinzu, die '$name makes a sound' ausgibt.
    • Eine Guitar-Klasse, die Instrument erweitert und play() überschreibt, um '$name strums melodically' auszugeben.
    • Eine Drum-Klasse, die Instrument erweitert und play() überschreibt, um '$name beats rhythmically' auszugeben.
    • Eine Piano-Klasse, die Instrument erweitert und play() überschreibt, um '$name plays harmoniously' auszugeben.
    Erstellen Sie außerdem eine Funktion performConcert(List<Instrument> instruments), die 'Concert begins!' ausgibt, dann die Liste durchläuft und play() für jedes Instrument aufruft und schließlich 'Concert ends!' ausgibt.
  • main.dart: Importieren Sie Ihre Instrumentendatei und demonstrieren Sie Polymorphismus, indem Sie eine gemischte Band erstellen:
    • Erstellen Sie eine Liste vom Typ List<Instrument>, die eine Guitar namens 'Acoustic', eine Drum namens 'Snare' und ein Piano namens 'Grand' enthält.
    • Übergeben Sie diese Liste an performConcert().

Beachten Sie, wie performConcert() mit dem Elterntyp Instrument arbeitet, obwohl jedes Instrument auf seine eigene, einzigartige Weise spielt. Dies ist Polymorphismus - derselbe Methodenaufruf erzeugt unterschiedliches Verhalten basierend auf dem tatsächlichen Objekttyp.

Erwartete Ausgabe:

Concert begins!
Acoustic strums melodically
Snare beats rhythmically
Grand plays harmoniously
Concert ends!

Spickzettel

Polymorphismus bedeutet "viele Formen" – er ermöglicht es Ihnen, Objekte verschiedener Klassen über eine gemeinsame Schnittstelle zu behandeln. Eine Referenz der Elternklasse kann auf jedes Objekt einer Kindklasse verweisen, und die korrekte Methode wird basierend auf dem tatsächlichen Objekttyp zur Laufzeit aufgerufen.

Grundlegendes Beispiel für Polymorphismus:

class Animal {
  void speak() => print('Some sound');
}

class Dog extends Animal {
  @override
  void speak() => print('Woof!');
}

class Cat extends Animal {
  @override
  void speak() => print('Meow!');
}

void main() {
  Animal myPet = Dog();  // Elterntyp, Kindobjekt
  myPet.speak();  // Ausgabe: Woof!
  
  myPet = Cat();  // Dieselbe Variable, anderes Objekt
  myPet.speak();  // Ausgabe: Meow!
}

Polymorphismus ermöglicht flexible Funktionen, die mit jeder Unterklasse funktionieren:

void makeAllSpeak(List<Animal> animals) {
  for (var animal in animals) {
    animal.speak();  // Jedes Tier spricht auf seine eigene Weise
  }
}

void main() {
  var pets = [Dog(), Cat(), Dog()];
  makeAllSpeak(pets);
  // Ausgabe: Woof! Meow! Woof!
}

Die Funktion arbeitet mit dem Elterntyp Animal, ohne über spezifische Kindklassen wie Dog oder Cat Bescheid wissen zu müssen. Dies macht den Code erweiterbarer – das Hinzufügen neuer Typen erfordert keine Änderungen an bestehenden Funktionen.

Probier es selbst

import 'instruments.dart';

void main() {
  // TODO: Erstelle eine List<Instrument>, die Folgendes enthält:
  // - Eine Guitar namens 'Acoustic'
  // - Eine Drum namens 'Snare'
  // - Ein Piano namens 'Grand'
  
  
  // TODO: Rufe performConcert() mit deiner Liste von Instrumenten auf
  
}
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