Ereditarietà singola e multilivello
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 25 di 87.
Finora abbiamo visto classi che estendono direttamente una classe genitore. Ma l'ereditarietà può formare strutture diverse a seconda di come le classi sono correlate tra loro. Esploriamo i due schemi principali: ereditarietà singola ed ereditarietà multilivello.
L’ereditarietà singola è quella che abbiamo usato finora. Una classe estende direttamente esattamente una classe genitore:
public class Animal { }
public class Dog extends Animal { }
public class Cat extends Animal { }Qui, sia Dog sia Cat ereditano da Animal, ma non ereditano l'uno dall'altra. Ogni classe figlia ha un solo genitore diretto.
L'ereditarietà multilivello crea una catena in cui una classe estende un'altra classe, che a sua volta estende un'altra classe:
public class Animal {
public void eat() {
System.out.println("Eating");
}
}
public class Mammal extends Animal {
public void breathe() {
System.out.println("Breathing");
}
}
public class Dog extends Mammal {
public void bark() {
System.out.println("Barking");
}
}In questa catena, Dog eredita da Mammal, che eredita da Animal. Un oggetto Dog ha accesso a tutti i metodi dell'intera catena:
Dog dog = new Dog();
dog.eat(); // Da Animal
dog.breathe(); // Da Mammal
dog.bark(); // Da DogRicorda che Object si trova in cima a ogni catena. Quindi il nostro Dog ha in realtà quattro livelli: Object -> Animal -> Mammal -> Dog. Il concatenamento dei costruttori attraversa tutti questi livelli quando viene creato un nuovo oggetto.
Sfida
FacileCostruiamo una gerarchia di mezzi di trasporto che dimostri sia l’ereditarietà singola sia quella multilivello. Creerai una catena di classi in cui ogni livello aggiunge nuove funzionalità, mostrando come i metodi vengono ereditati attraverso più livelli.
Organizzerai il codice in quattro file:
Vehicle.java: crea la classe base in cima alla gerarchia. Ogni veicolo dovrebbe avere:- Un campo privato per
brand(String) - Un costruttore che accetta il marchio
- Un metodo
getBrand()che restituisce il marchio - Un metodo
move()che stampa:[brand] is moving
- Un campo privato per
LandVehicle.java: crea una classe che estende Vehicle e rappresenta il livello intermedio della catena multilivello. I veicoli terrestri aggiungono comportamenti specifici per la strada:- Un campo privato per
wheels(int) - Un costruttore che accetta il marchio e il numero di ruote, usando
super(brand)per la parte relativa alla classe genitore - Un metodo
getWheels()che restituisce il numero di ruote - Un metodo
honk()che stampa:[brand] honks!
- Un campo privato per
Car.java: crea una classe che estende LandVehicle, completando la catena di ereditarietà a tre livelli. Le auto aggiungono funzionalità specifiche:- Un campo privato per
model(String) - Un costruttore che accetta il marchio, il numero di ruote e il modello, usando
super(brand, wheels) - Un metodo
getModel()che restituisce il modello - Un metodo
displayInfo()che stampa:[brand] [model] with [wheels] wheels
- Un campo privato per
Main.java: dimostra come un oggetto Car possa accedere ai metodi di tutti e tre i livelli della gerarchia. Riceverai tre input: marchio (String), numero di ruote (int) e modello (String). Crea una Car e chiama questi metodi nell’ordine indicato:move()- ereditato da Vehicle (nonno)honk()- ereditato da LandVehicle (genitore)displayInfo()- definito nella classe Car stessa
Riceverai tre input: il nome del marchio, il numero di ruote e il nome del modello.
L’output dovrebbe mostrare tre righe che dimostrano come l’oggetto Car possa usare metodi di ogni livello della sua catena di ereditarietà, dal livello più alto, Vehicle, fino alla propria classe!
Provalo tu
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi i dati di input
String brand = scanner.nextLine();
int wheels = scanner.nextInt();
scanner.nextLine(); // consuma il carattere di nuova riga
String model = scanner.nextLine();
// TODO: Crea un oggetto Car con i valori di input
// TODO: Chiama move() - ereditato da Vehicle (classe nonna)
// TODO: Chiama honk() - ereditato da LandVehicle (classe genitore)
// TODO: Chiama displayInfo() - definito nella classe Car stessa
}
}
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