Adnotacja @override
Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 39 z 110.
Adnotacja @override to znacznik dobrej praktyki, który informuje Dart (i innych programistów), że celowo zastępujesz metodę z klasy nadrzędnej. Choć nadpisywanie metod działa bez niej, użycie @override zapewnia ważną dodatkową ochronę.
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void speak() {
print('$name barks: Woof!');
}
}Adnotacja zapewnia dwie kluczowe korzyści. Po pierwsze, jasno dokumentuje Twoje zamiary — każda osoba czytająca kod od razu wie, że ta metoda istnieje w klasie nadrzędnej. Po drugie, analizator Dart ostrzeże Cię, jeśli metoda nadrzędna w rzeczywistości nie istnieje, dzięki czemu literówki i błędy podczas refaktoryzacji zostaną wykryte na wczesnym etapie.
Zastanów się, co się stanie, jeśli błędnie zapiszesz nazwę metody bez @override:
class Cat extends Animal {
Cat(String name) : super(name);
void speek() { // Literówka! Bez @override nie ma ostrzeżenia
print('$name meows');
}
}Bez adnotacji Dart zakłada, że tworzysz nową metodę o nazwie speek(). Dzięki @override analizator natychmiast zgłosi, że taka metoda nie istnieje w klasie nadrzędnej. Ta prosta adnotacja zapobiega subtelnym błędom, które później mogą być trudne do wykrycia.
Wyzwanie
ŁatwyZbudujmy system odtwarzacza multimediów, który pokaże, jak ważna jest adnotacja @override podczas dostosowywania odziedziczonego zachowania. Utworzysz różne typy mediów, z których każdy odtwarza treści na swój sposób.
Podzielisz kod na dwa pliki:
media.dart: Zdefiniuj tutaj hierarchię mediów:- Klasa
Mediaz właściwościąString title, konstruktorem przyjmującym tytuł oraz metodąplay(), która wyświetlaPlaying: [title] - Klasa
Song, która rozszerzaMediai dodaje właściwośćString artist. Użyj adnotacji@overridei przesłoń metodęplay(), aby wyświetlałaPlaying song: [title] by [artist] - Klasa
Video, która rozszerzaMediai dodaje właściwośćint duration(w sekundach). Użyj@overridei przesłoń metodęplay(), aby najpierw wywołać wersję z klasy nadrzędnej za pomocąsuper.play(), a następnie wyświetlićDuration: [duration] seconds
- Klasa
main.dart: Zaimportuj plik z mediami i zademonstruj przesłonięte metody:- Utwórz obiekt
Mediaz tytułem'Generic Content'i wywołajplay() - Wyświetl pusty wiersz
- Utwórz obiekt
Songz tytułem'Imagine'i wykonawcą'John Lennon', a następnie wywołajplay() - Wyświetl pusty wiersz
- Utwórz obiekt
Videoz tytułem'Dart Tutorial'i czasem trwania360, a następnie wywołajplay()
- Utwórz obiekt
Adnotacja @override dokumentuje Twoje zamiary i pomaga wykrywać błędy. Jeśli przypadkowo napiszesz plya() zamiast play(), adnotacja poinformuje Cię, że taka metoda nie istnieje w klasie nadrzędnej.
Oczekiwany wynik:
Playing: Generic Content
Playing song: Imagine by John Lennon
Playing: Dart Tutorial
Duration: 360 secondsSpróbuj swoich sił
import 'media.dart';
void main() {
// TODO: Utwórz obiekt Media z tytułem 'Generic Content' i wywołaj play()
// TODO: Wypisz pustą linię
// TODO: Utwórz obiekt Song z tytułem 'Imagine' i artystą 'John Lennon', a następnie wywołaj play()
// TODO: Wypisz pustą linię
// TODO: Utwórz obiekt Video z tytułem 'Dart Tutorial' i czasem trwania 360, a następnie wywołaj play()
}
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