Sovrascrittura dei metodi (@Override)
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 22 di 87.
L'override dei metodi consente a una sottoclasse di fornire la propria implementazione di un metodo già definito nella sua classe genitore. È così che le classi figlie personalizzano il comportamento ereditato per adattarlo alle proprie esigenze specifiche.
Quando esegui l'override di un metodo, la versione della sottoclasse sostituisce completamente quella della classe padre per gli oggetti di quella sottoclasse. Il metodo deve avere lo stesso nome e gli stessi parametri del metodo della classe padre e un tipo restituito uguale a quello del metodo della classe padre (o un suo sottotipo):
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}L'annotazione @Override comunica al compilatore che intendi sovrascrivere un metodo della classe padre. Sebbene sia facoltativa, è fortemente consigliata perché il compilatore rileverà gli errori se scrivi accidentalmente male il nome del metodo o usi parametri errati:
@Override
public void makeSound() { } // Corretto - il compilatore lo verifica
public void makesound() { } // Errore di battitura! Crea un nuovo metodo invece di sovrascrivere quello esistenteQuando chiami un metodo sovrascritto, Java esegue la versione che appartiene al tipo effettivo dell'oggetto:
Dog dog = new Dog();
dog.makeSound(); // Output: Woof!
Cat cat = new Cat();
cat.makeSound(); // Output: Meow!Ricorda dalla lezione precedente che puoi usare super.methodName() all'interno di un metodo sovrascritto se vuoi comunque includere il comportamento della classe genitore insieme al tuo nuovo codice.
Sfida
FacileCostruiamo un sistema di notifiche che mostri come le sottoclassi possano sovrascrivere i metodi della classe genitore per fornire un comportamento specializzato. Vedrai come l'annotazione @Override aiuta a individuare gli errori e come ogni sottoclasse può personalizzare i metodi ereditati.
Creerai tre file per organizzare il codice:
Notification.java: crea la classe genitore che rappresenta una notifica generica. Dovrebbe avere:- Un campo privato per il
message(String) - Un costruttore che accetta il messaggio
- Un metodo
getMessage()che restituisce il messaggio - Un metodo
send()che stampa:Sending notification: [message]
- Un campo privato per il
EmailNotification.java: crea una sottoclasse che estende Notification e personalizza il modo in cui le notifiche vengono inviate via email:- Un campo privato per l'indirizzo email del
recipient(String) - Un costruttore che accetta sia il messaggio sia il destinatario, usando
super(message)per la parte della classe genitore - Sovrascrivi il metodo
send()usando l'annotazione@Overrideper stampare:Emailing [recipient]: [message]
- Un campo privato per l'indirizzo email del
Main.java: mostra come lo stesso nome di metodo produca comportamenti diversi a seconda del tipo di oggetto. Riceverai due input: un messaggio e un indirizzo email. Crea sia un Notification normale sia un EmailNotification con lo stesso messaggio, poi chiamasend()su entrambi per vedere i diversi output.
Riceverai due input: il messaggio (String) e l'indirizzo email del destinatario (String).
L'output dovrebbe mostrare due righe: prima quella del metodo send() della classe genitore, poi quella della versione sovrascritta in EmailNotification. Questo dimostra come la sovrascrittura dei metodi consenta alle sottoclassi di sostituire il comportamento ereditato con una propria implementazione.
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi i dati in input
String message = scanner.nextLine();
String recipient = scanner.nextLine();
// TODO: Crea un oggetto Notification con message
// TODO: Crea un oggetto EmailNotification con message e recipient
// TODO: Chiama send() sull'oggetto Notification
// TODO: Chiama send() sull'oggetto EmailNotification
}
}
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 a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online