L’annotazione @override
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 39 di 110.
L'annotazione @override è un contrassegno di buona pratica che comunica a Dart (e agli altri sviluppatori) che stai intenzionalmente sovrascrivendo un metodo di una classe genitore. Sebbene la sovrascrittura dei metodi funzioni anche senza, usare @override aggiunge un'importante rete di sicurezza.
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!');
}
}L'annotazione offre due vantaggi fondamentali. Innanzitutto, documenta chiaramente la tua intenzione: chiunque legga il codice capisce subito che questo metodo esiste nella classe genitore. In secondo luogo, l'analizzatore di Dart ti avviserà se il metodo genitore non esiste davvero, aiutandoti a individuare tempestivamente refusi ed errori di refactoring.
Considera cosa succede se scrivi in modo errato il nome del metodo senza @override:
class Cat extends Animal {
Cat(String name) : super(name);
void speek() { // Refuso! Nessun avviso senza @override
print('$name meows');
}
}Senza l'annotazione, Dart presume che tu stia creando un nuovo metodo chiamato speek(). Con @override, l'analizzatore segnalerebbe immediatamente che nella classe genitore non esiste alcun metodo del genere. Questa semplice annotazione previene bug sottili che potrebbero essere difficili da individuare in seguito.
Sfida
FacileCostruiamo un sistema di riproduzione multimediale che dimostri l'importanza dell'annotazione @override quando si personalizza il comportamento ereditato. Creerai diversi tipi di contenuti multimediali, ognuno dei quali riproduce i contenuti a modo proprio.
Organizzerai il codice in due file:
media.dart: definisci qui la gerarchia dei contenuti multimediali:- Una classe
Mediacon una proprietàString title, un costruttore che accetta il titolo e un metodoplay()che stampaPlaying: [title] - Una classe
Songche estendeMediae aggiunge una proprietàString artist. Usa l'annotazione@overridee sovrascriviplay()per stamparePlaying song: [title] by [artist] - Una classe
Videoche estendeMediae aggiunge una proprietàint duration(in secondi). Usa@overridee sovrascriviplay()per chiamare prima la versione della classe genitore consuper.play(), quindi stampareDuration: [duration] seconds
- Una classe
main.dart: importa il tuo file multimediale e mostra i metodi sovrascritti:- Crea un oggetto
Mediacon il titolo'Generic Content'e chiamaplay() - Stampa una riga vuota
- Crea un
Songcon il titolo'Imagine'e l'artista'John Lennon', poi chiamaplay() - Stampa una riga vuota
- Crea un
Videocon il titolo'Dart Tutorial'e una durata di360, poi chiamaplay()
- Crea un oggetto
L'annotazione @override documenta la tua intenzione e aiuta a individuare gli errori. Se per sbaglio scrivessi plya() invece di play(), l'annotazione ti avviserebbe che nella classe genitore non esiste un metodo con quel nome.
Risultato previsto:
Playing: Generic Content
Playing song: Imagine by John Lennon
Playing: Dart Tutorial
Duration: 360 secondsProvalo tu
import 'media.dart';
void main() {
// TODO: Crea un oggetto Media con titolo 'Generic Content' e chiama play()
// TODO: Stampa una riga vuota
// TODO: Crea un oggetto Song con titolo 'Imagine' e artista 'John Lennon', poi chiama play()
// TODO: Stampa una riga vuota
// TODO: Crea un oggetto Video con titolo 'Dart Tutorial' e durata 360, poi chiama play()
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniLibrerie e importazioniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave thisMetodiVariabili di istanzaFondamenti dei costruttoriRiepilogo - Calcolatrice semplice4Sicurezza dei valori null
Introduzione alla sicurezza dei valori nullNullable e non nullableGli operatori ? e !La keyword late e la sicurezza dei valori nullOperatori null-awareSicurezza dei valori null nelle classiRiepilogo - Sistema di profili utente7Classi astratte e interfacce
Classi astratteMetodi astrattiInterfacce in DartInterfacce impliciteImplementare vs estendereInterfacce multipleRiepilogo - Calcolatore di forme10Collezioni e generici
Panoramica di List, Set e MapCollezioni sicure rispetto ai tipiClassi genericheMetodi genericiVincoli sui genericiIterable e IteratorRiepilogo - Archiviazione generica13Concetti avanzati di OOP
Composizione vs ereditarietàMetodi di estensioneClassi chiamabiliClassi sealed (Dart 3)Record (Dart 3)Pattern e matching (3.0)Enum con metodi16Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente2I costruttori in Dart
Costruttore predefinitoCostruttori con nomeListe di inizializzazioneCostruttori costantiCostruttori factoryCostruttori di reindirizzamentoRiepilogo - Crea forme5Incapsulamento
Membri pubblici e privatiConvenzione del prefisso _Visibilità a livello di libreriaApprofondimento su getter e setterNascondimento delle informazioniRiepilogo - Registri degli studenti8Mixin
Introduzione ai MixinCreare MixinUsare più MixinParola chiave on nei MixinMixin vs ereditarietàMixin vs interfacciaRiepilogo - Sistema animale11Metodi speciali
Sovrascrittura di toString()Sovrascrittura di hashCode e ==Interfaccia ComparableMetodo call()Sovrascrittura di noSuchMethodRiepilogo - Collezione personalizzata14Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneSingletonFactoryObserverStrategy3Proprietà delle classi
Membri di istanza e staticiCampi final e constVariabili lateMetodi e campi staticiGetter e setterRiepilogo - Gestore di conti bancari6Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiL’annotazione @overrideLa parola chiave final per le classiCostruttori ed ereditarietàRiepilogo - Gerarchia dei dipendenti9Polimorfismo
Fondamenti di polimorfismoPolimorfismo tramite interfacceControllo del tipo a runtimeGli operatori is e asParola chiave covariantRiepilogo - Elaboratore di pagamenti12OOP asincrona
Future e async/awaitNozioni di base sugli streamController degli streamCostruttori asincroniAsync nei metodi di classeRiepilogo - Recupero dei dati15Pattern di progettazione Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern RepositoryEsercitati da solo: Compilatore Dart online