Menu
Coddy logo textTech

Podstawy polimorfizmu

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 57 z 110.

Polimorfizm oznacza „wiele form” — to możliwość traktowania obiektów różnych klas za pomocą wspólnego interfejsu. Odwołanie do klasy nadrzędnej może wskazywać na obiekt dowolnej klasy potomnej, a wywołana zostaje właściwa metoda, zależnie od rzeczywistego typu obiektu.

To jest potężne, ponieważ możesz napisać kod działający z typem nadrzędnym, a jednocześnie automatycznie poprawnie obsługujący wszystkie typy podrzędne:

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();  // Typ rodzica, obiekt klasy potomnej
  myPet.speak();  // Wynik: Woof!
  
  myPet = Cat();  // Ta sama zmienna, inny obiekt
  myPet.speak();  // Wynik: Meow!
}

Zmienna myPet jest zadeklarowana jako Animal, ale przechowuje obiekt typu Dog lub Cat. Gdy wywoływana jest metoda speak(), Dart sprawdza rzeczywisty typ obiektu w czasie wykonywania i wywołuje odpowiednią nadpisaną metodę.

Pozwala ci to pisać elastyczne funkcje, które działają z dowolną podklasą:

void makeAllSpeak(List<Animal> animals) {
  for (var animal in animals) {
    animal.speak();  // Każde zwierzę odzywa się na swój sposób
  }
}

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

Funkcja nie musi wiedzieć o Dog ani Cat — działa po prostu z Animal. Dzięki temu Twój kod jest bardziej rozszerzalny, ponieważ dodawanie nowych typów zwierząt nie wymaga zmian w istniejących funkcjach.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system instrumentów muzycznych, który pokaże polimorfizm w praktyce. Utworzysz bazową klasę Instrument i kilka typów instrumentów, a następnie napiszesz funkcję, która pozwoli dowolnemu zestawowi instrumentów grać razem — bez znajomości ich konkretnych typów.

Podzielisz swój kod na dwa pliki:

  • instruments.dart: Zdefiniuj tutaj hierarchię instrumentów:
    • Klasę Instrument z właściwością String name i konstruktorem. Dodaj metodę play(), która wypisuje [name] makes a sound
    • Klasę Guitar, która rozszerza klasę Instrument i nadpisuje metodę play(), aby wypisywała [name] strums melodically
    • Klasę Drum, która rozszerza klasę Instrument i nadpisuje metodę play(), aby wypisywała [name] beats rhythmically
    • Klasę Piano, która rozszerza klasę Instrument i nadpisuje metodę play(), aby wypisywała [name] plays harmoniously
    Utwórz też funkcję performConcert(List<Instrument> instruments), która wypisuje Concert begins!, następnie przechodzi przez listę, wywołując play() dla każdego instrumentu, a na końcu wypisuje Concert ends!
  • main.dart: Zaimportuj plik z instrumentami i pokaż polimorfizm, tworząc zespół złożony z różnych instrumentów:
    • Utwórz listę typu List<Instrument>, zawierającą Guitar o nazwie 'Acoustic', Drum o nazwie 'Snare' oraz Piano o nazwie 'Grand'
    • Przekaż tę listę do funkcji performConcert()

Zwróć uwagę, że funkcja performConcert() działa z typem nadrzędnym Instrument, a mimo to każdy instrument gra na swój wyjątkowy sposób. To właśnie polimorfizm — to samo wywołanie metody daje różne zachowanie w zależności od rzeczywistego typu obiektu.

Oczekiwany wynik:

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

Spróbuj swoich sił

import 'instruments.dart';

void main() {
  // TODO: Utwórz List<Instrument> zawierającą:
  // - Guitar o nazwie 'Acoustic'
  // - Drum o nazwie 'Snare'
  // - Piano o nazwie 'Grand'
  
  
  // TODO: Wywołaj performConcert() ze swoją listą instrumentów
  
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online