Podstawy dziedziczenia
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 36 z 110.
Dziedziczenie pozwala klasie przejąć właściwości i metody innej klasy. Zamiast przepisywać ten sam kod, tworzysz nową klasę, która bazuje na istniejącej. Oryginalna klasa nazywa się klasą nadrzędną (lub nadklasą), a nowa klasa to klasa potomna (lub podklasa).
W Dart używasz słowa kluczowego extends, aby dziedziczyć po klasie nadrzędnej:
class Animal {
String name;
Animal(this.name);
void eat() {
print('$name is eating');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
void bark() {
print('$name says woof!');
}
}
void main() {
var dog = Dog('Buddy');
dog.eat(); // Odziedziczone po Animal
dog.bark(); // Zdefiniowane w Dog
}Klasa Dog automatycznie ma dostęp do właściwości name i metody eat() z klasy Animal, a także do własnej metody bark(). Tworzy to relację „jest” — Dog jest Animal.
Klasa potomna może dodawać nowe właściwości i metody, ale dziedziczy wszystko, co publiczne, z klasy nadrzędnej. Pamiętaj, że składowe prywatne (te z _) nie są bezpośrednio dostępne w podklasach z innych bibliotek, choć nadal istnieją w odziedziczonym obiekcie.
Wyzwanie
ŁatwyZbudujmy system pojazdów, który pokaże, jak dziedziczenie pozwala klasom potomnym ponownie wykorzystywać i rozszerzać funkcjonalność klas nadrzędnych. Utworzysz klasę nadrzędną dla ogólnych pojazdów oraz klasę potomną dla konkretnego typu pojazdu.
Uporządkujesz kod w dwóch plikach:
vehicle.dart: Zdefiniuj tutaj swoje klasy:- Klasa
Vehicle(nadrzędna) z właściwościąString brand, konstruktorem przyjmującym markę oraz metodąstart(), która wyświetla[brand] engine starting... - Klasa
Motorcycle, która rozszerza klasęVehicle. Powinna mieć dodatkową właściwośćint cc(pojemność skokowa silnika), konstruktor przyjmujący zarówno markę, jak i cc (przekazujący markę klasie nadrzędnej za pomocąsuper) oraz własną metodęwheelie(), która wyświetla[brand] is doing a wheelie!
- Klasa
main.dart: Zaimportuj plik pojazdu i pokaż działanie dziedziczenia:- Utwórz obiekt
Vehicleo marce'Toyota' - Wywołaj jego metodę
start() - Utwórz obiekt
Motorcycleo marce'Harley'i cc1200 - Wywołaj metodę
start()motocykla (odziedziczoną z klasy Vehicle) - Wywołaj metodę
wheelie()motocykla (zdefiniowaną w klasie Motorcycle) - Wyświetl
Motorcycle engine: [cc]cc, aby pokazać własną właściwość klasy potomnej
- Utwórz obiekt
Zwróć uwagę, jak klasa Motorcycle automatycznie uzyskuje dostęp do właściwości brand i metody start() z klasy Vehicle, a jednocześnie ma własną, unikatową właściwość cc i metodę wheelie(). Na tym polega siła dziedziczenia — budowaniu na istniejącym kodzie.
Oczekiwany wynik:
Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200ccSpróbuj swoich sił
import 'vehicle.dart';
void main() {
// TODO: Utwórz obiekt Vehicle z marką 'Toyota'
// TODO: Wywołaj metodę start() pojazdu
// TODO: Utwórz obiekt Motorcycle z marką 'Harley' i cc 1200
// TODO: Wywołaj metodę start() motocykla (odziedziczoną po Vehicle)
// TODO: Wywołaj metodę wheelie() motocykla
// TODO: Wypisz 'Motorcycle engine: [cc]cc', używając właściwości cc motocykla
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatnościPoćwicz samodzielnie: Kompilator Dart online