Aggregazione vs composizione
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 48 di 87.
Sia l’aggregazione che la composizione sono forme di relazioni «ha un», ma differiscono per un aspetto cruciale: la proprietà e la dipendenza dal ciclo di vita.
Nella composizione, l'oggetto contenuto non può esistere indipendentemente dal contenitore. Quando il contenitore viene distrutto, lo stesso accade alle sue parti. Pensa a una House e ai suoi oggetti Room: le stanze non esistono senza la casa:
class House {
private Room[] rooms;
public House(int numRooms) {
rooms = new Room[numRooms];
for (int i = 0; i < numRooms; i++) {
rooms[i] = new Room(); // House crea e possiede le stanze
}
}
}Nell’aggregazione, l’oggetto contenuto può esistere indipendentemente. Il contenitore usa l’oggetto, ma non ne controlla il ciclo di vita. Considera una Team e i suoi oggetti Player: i giocatori esistono anche senza una squadra:
class Team {
private List<Player> players;
public Team() {
players = new ArrayList<>();
}
public void addPlayer(Player player) {
players.add(player); // Team utilizza i giocatori esistenti
}
}La distinzione fondamentale: nella composizione, il contenitore crea internamente le sue parti. Nell’aggregazione, gli oggetti vengono passati dall’esterno. Quando un Team viene eliminato, gli oggetti Player esistono ancora. Quando una House viene eliminata, anche i suoi oggetti Room scompaiono.
Sfida
FacileCostruiamo un sistema di corsi universitari che dimostri sia l’aggregazione sia la composizione. Vedrai come un Course possiede i propri oggetti Lecture (composizione), mentre fa riferimento soltanto a oggetti Professor che esistono in modo indipendente (aggregazione).
Organizzerai il codice in quattro file:
Professor.java: crea una classe che rappresenti un professore che può esistere indipendentemente da qualsiasi corso. Un Professor ha due campi privati:name(String) edepartment(String). Includi un costruttore per inizializzare entrambi i campi e metodi getter per ciascuno. SovrascrivitoString()affinché restituisca:Prof. [name] ([department])Lecture.java: crea una classe che rappresenti una lezione che ha senso solo all’interno di un corso. Una Lecture ha due campi privati:topic(String) edurationMinutes(int). Includi un costruttore e i metodi getter. SovrascrivitoString()affinché restituisca:Lecture: [topic] ([durationMinutes] min)Course.java: qui dimostrerai entrambe le relazioni! Un Course ha tre campi privati:title(String),professor(Professor - aggregazione) electures(un array di oggetti Lecture - composizione).Il costruttore accetta il titolo del corso, un oggetto Professor (passato dall’esterno: aggregazione) e il numero di lezioni. All’interno del costruttore, crea l’array di Lecture e popolalo con nuovi oggetti Lecture. Per ogni lezione all’indice
i, creala con l’argomento"Topic " + (i + 1)e una durata di45minuti. Questa creazione interna dimostra la composizione.Aggiungi un metodo
getInfo()che restituisca una Stringa su più righe:Course: [title] Instructor: [professor.toString()] Lectures: [number of lectures]Aggiungi anche un metodo
listLectures()che restituisca una Stringa con il toString() di ogni lezione su una riga distinta.Main.java: metti insieme tutti gli elementi! Riceverai quattro input: nome del professore (String), dipartimento del professore (String), titolo del corso (String) e numero di lezioni (int).Per prima cosa, crea un Professor con il nome e il dipartimento forniti. Questo professore esiste in modo indipendente. Poi crea un Course, passandogli il titolo, il professore (aggregazione) e il numero di lezioni (il corso creerà le proprie lezioni al suo interno: composizione).
Stampa il risultato di
getInfo(), poi stampa una riga vuota e infine stampa il risultato dilistLectures().
Riceverai quattro input, in quest’ordine: nome del professore, dipartimento, titolo del corso e numero di lezioni.
Nota la differenza fondamentale: il Professor viene creato all’esterno e passato al Course (aggregazione: il professore potrebbe insegnare altri corsi o esistere senza questo corso). Le Lecture vengono create all’interno del costruttore di Course (composizione. Appartengono esclusivamente a questo corso e non esisterebbero senza di esso).
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi gli input
String professorName = scanner.nextLine();
String department = scanner.nextLine();
String courseTitle = scanner.nextLine();
int numberOfLectures = scanner.nextInt();
// TODO: Crea un oggetto Professor (esiste in modo indipendente - aggregazione)
// TODO: Crea un oggetto Course, passando il professore (aggregazione)
// Il corso creerà internamente le proprie lezioni (composizione)
// TODO: Stampa il risultato di getInfo()
// TODO: Stampa una riga vuota
// TODO: Stampa il risultato di listLectures()
}
}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