Menu
Coddy logo textTech

Override dei metodi (a runtime)

Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 29 di 87.

Mentre l'overloading dei metodi viene risolto in fase di compilazione, l'override dei metodi dimostra il polimorfismo a runtime. In questo caso, Java decide quale metodo eseguire mentre il programma è effettivamente in esecuzione, in base al tipo effettivo dell'oggetto anziché al tipo dichiarato della variabile.

Hai imparato l'override dei metodi nel capitolo Ereditarietà. Ciò che lo rende polimorfico è il modo in cui Java lo gestisce quando un riferimento alla classe genitore punta a un oggetto della classe figlia:

public class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

public class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Bark!");
    }
}

public class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Meow!");
    }
}

Ora osserva cosa succede quando usiamo riferimenti di tipo genitore:

Animal myPet = new Dog();
myPet.speak();  // Output: Bark!

myPet = new Cat();
myPet.speak();  // Output: Meow!

Anche se myPet è dichiarato come Animal, Java chiama il metodo sovrascritto in base al tipo effettivo dell’oggetto durante l’esecuzione. Questo si chiama invio dinamico dei metodi. La JVM considera ciò che l’oggetto è realmente, non ciò che indica la variabile.

Questo permette di usare schemi potenti, come elaborare oggetti diversi in modo uniforme:

Animal[] pets = {new Dog(), new Cat(), new Dog()};
for (Animal pet : pets) {
    pet.speak();  // Ognuno chiama la propria versione
}

Il polimorfismo a tempo di esecuzione ti permette di scrivere codice flessibile che funziona con i tipi genitore, utilizzando automaticamente il comportamento corretto dei tipi figli.

challenge icon

Sfida

Facile

Costruiamo un sistema di notifiche che dimostra il polimorfismo a tempo di esecuzione in azione. Creerai una gerarchia di tipi di notifica in cui la stessa chiamata a un metodo produce output diversi in base al tipo effettivo dell'oggetto durante l'esecuzione.

Organizzerai il codice in quattro file:

  • Notification.java: crea la classe base condivisa da tutte le notifiche. Ogni notifica ha un campo recipient (String). Includi un costruttore per inizializzarlo, un metodo getter e un metodo send() che stampa: Sending notification to [recipient]
  • EmailNotification.java: crea una classe che estende Notification. Le notifiche e-mail aggiungono un campo subject. Usa super per inizializzare la classe genitore. Sovrascrivi il metodo send() in modo che stampi: Emailing [recipient]: [subject]
  • SMSNotification.java: crea un'altra classe che estende Notification. Le notifiche SMS aggiungono un campo phoneNumber. Sovrascrivi send() in modo che stampi: Texting [phoneNumber] for [recipient]
  • Main.java: è qui che il polimorfismo a tempo di esecuzione dà il meglio di sé! Riceverai tre input: il nome di un destinatario, l'oggetto di un'e-mail e un numero di telefono. Crea un array di riferimenti Notification contenente tre oggetti in questo ordine: una Notification di base, una EmailNotification e una SMSNotification (tutte con lo stesso destinatario). Poi scorri l'array e chiama send() su ogni elemento. Osserva come Java chiama automaticamente la versione sovrascritta corretta in base al tipo effettivo di ciascun oggetto!

Riceverai tre input: il nome del destinatario (String), l'oggetto dell'e-mail (String) e il numero di telefono (String).

L'output dovrebbe mostrare tre righe: ogni chiamata a send() produce un output diverso, anche se stai chiamando lo stesso metodo su riferimenti Notification. È il polimorfismo dinamico in azione!

Provalo tu

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leggi gli input
        String recipient = scanner.nextLine();
        String subject = scanner.nextLine();
        String phoneNumber = scanner.nextLine();
        
        // TODO: Crea un array di riferimenti a Notification con 3 elementi
        // L'array deve contenere (in questo ordine):
        // 1. Un oggetto Notification di base
        // 2. Un oggetto EmailNotification
        // 3. Un oggetto SMSNotification
        // Tutti con lo stesso destinatario
        
        // TODO: Scorri l'array e chiama send() su ogni elemento
        // Questo dimostra il polimorfismo a runtime!
    }
}
quiz iconMettiti alla prova

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

Esercitati da solo: Compilatore Java online