Menu
Coddy logo textTech

Implementowanie a rozszerzanie

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

Skoro rozumiesz już zarówno extends, jak i implements, wyjaśnijmy, kiedy używać każdego z nich.

Używaj extends, gdy chcesz dziedziczyć zachowanie. Twoja podklasa otrzymuje cały kod klasy nadrzędnej za darmo i może go rozbudowywać:

class Animal {
  void breathe() {
    print('Breathing...');
  }
}

class Dog extends Animal {
  void bark() {
    print('Woof!');
  }
}

void main() {
  var dog = Dog();
  dog.breathe();  // Odziedziczone - działa automatycznie
  dog.bark();
}

Użyj implements, gdy chcesz zagwarantować strukturę bez dziedziczenia kodu. Każdą metodę musisz napisać samodzielnie:

class Robot implements Animal {
  @override
  void breathe() {
    print('Ventilating circuits...');  // Implementacja całkowicie niestandardowa
  }
}

Kluczowa różnica: extends oznacza „jestem typem tego”, a implements — „potrafię robić to, co to”. Dog jest Animal i oddycha w ten sam sposób. Robot nie jest zwierzęciem, ale może spełniać ten sam kontrakt, stosując własną logikę.

Pamiętaj: możesz rozszerzyć tylko jedną klasę, ale możesz implementować wiele interfejsów. Wybierz extends w przypadku rzeczywistych relacji dziedziczenia, a implements, gdy potrzebujesz elastyczności lub chcesz wymusić kontrakt bez współdzielenia szczegółów implementacji.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system pracowników, który pokazuje, kiedy używać extends, a kiedy implements. Utworzysz bazową klasę pracownika, a następnie pokażesz oba podejścia: jedną klasę, która naprawdę „jest” pracownikiem i dziedziczy zachowanie, oraz drugą, która po prostu „potrafi robić” to, co robi pracownik, ale stosuje całkowicie własną logikę.

Podzielisz kod na dwa pliki:

  • worker.dart: Zdefiniuj tutaj hierarchię pracowników:
    • Klasę Worker z właściwością String name i konstruktorem. Dodaj metodę work(), która wyświetla [name] is working..., oraz metodę takeBreak(), która wyświetla [name] takes a coffee break
    • Klasę OfficeWorker, która extends Worker. Dodaj właściwość String department. Zastąp metodę work(), aby wyświetlała [name] is typing reports in [department], ale zachowaj odziedziczone zachowanie metody takeBreak()
    • Klasę RobotWorker, która implements Worker. Dodaj właściwość String model. Ponieważ roboty tak naprawdę nie są pracownikami, ale potrafią robić to, co robią pracownicy, przygotuj całkowicie własne implementacje: work() powinna wyświetlać Robot [model] is assembling parts, a takeBreak() powinna wyświetlać Robot [model] is recharging
  • main.dart: Zaimportuj plik z pracownikami i pokaż oba podejścia:
    • Utwórz OfficeWorker o imieniu 'Alice' w dziale 'Marketing'
    • Utwórz RobotWorker z modelem 'RX-7'
    • W przypadku pracownika biurowego wywołaj work(), a następnie takeBreak()
    • Wyświetl pusty wiersz
    • W przypadku pracownika-robota wywołaj work(), a następnie takeBreak()

Zwróć uwagę, że OfficeWorker automatycznie dziedziczy metodę takeBreak(), ponieważ rozszerza klasę Worker — naprawdę „jest” pracownikiem. Tymczasem RobotWorker musi samodzielnie zaimplementować wszystko, ponieważ implementuje jedynie interfejs — „potrafi robić” to, co robi pracownik, ale na swój własny, robotyczny sposób.

Oczekiwany wynik:

Alice is typing reports in Marketing
Alice takes a coffee break

Robot RX-7 is assembling parts
Robot RX-7 is recharging

Spróbuj swoich sił

import 'worker.dart';

void main() {
  // TODO: Utwórz obiekt OfficeWorker o imieniu 'Alice' w dziale 'Marketing'
  
  // TODO: Utwórz obiekt RobotWorker z modelem 'RX-7'
  
  // TODO: Dla pracownika biurowego wywołaj work(), a następnie takeBreak()
  
  // TODO: Wypisz pustą linię
  
  // TODO: Dla pracownika robota wywołaj work(), a następnie takeBreak()
}
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