Introduzione all’Ereditarietà Pietro Palladino
Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce le proprietà e le funzionalità delle sue istanze (oggetti)
Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce le proprietà e le funzionalità delle sue istanze (oggetti) Persona
Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Proprietà: attributi Persona nome: String
Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Funzionalità: metodi Persona nome: String scriviNome(): void
Richiami UML Relazione Una connessione tra due classi Persona nome: String scriviNome(): void Indirizzo via: String getCittà(): String
Richiami UML Relazione Una connessione tra due classi La molteplicità indica quanti oggetti di una classe possono far riferimento ad ogni oggetto dell'altra Persona nome: String scriviNome(): void Indirizzo via: String getCittà(): String * 1
Ereditarietà Principio che consente a una classe di ereditare le variabili e i metodi di un’altra classe Consente di raffinare le caratteristiche di classi di oggetti a partire da classi generali riutilizzo del codice
Relazione stabilita tra due classi La classe destinazione è la superclasse e definisce un concetto generale La classe sorgente è la sottoclasse e definisce una specializzazione della superclasse Ereditarietà Studente classe: String Persona nome: String scriviNome(): void
Alcuni esempi Animale respira(): void
Alcuni esempi PesceAnimale respira(): void
Alcuni esempi UccelloAnimale respira(): void Pesce
Alcuni esempi UccelloPesceAnimale respira(): void Squalo
Alcuni esempi UccelloPesceAnimale respira(): void SqualoAquila
Alcuni esempi Uccello vola(): void Pesce nuota(): void Animale respira(): void SqualoAquila
Perché? Permette di riutilizzare il codice delle classi già definite Posso definire un nuovo Pesce senza preoccuparmi di dover ridefinire come respira Le nuove classi aggiungono funzionalità ma sono COMPATIBILI con le vecchie Posso definire un nuovo tipo di Uccello e utilizzarlo come se fosse un Uccello o un Animale e basta Posso non dover/voler conoscere il tipo specifico! principio di sostituibilità
Proprietà La classe Animale è la classe base/superclasse La classe Pesce è la classe derivata/specializzata Le classi create definiscono una gerarchia Una classe può estendere SOLO un’altra classe Può essere estesa da n classi Albero delle classi
Sintassi Java In Java, l’ereditarietà si definisce utilizzando la parola chiave extends Quando omesso, le classi estendono Object class Animale { … } class Pesce extends Animale { … }
Sintassi Java La classe derivata eredita tutte le variabili e i metodi della classe base La classe derivata NON eredita il costruttore Se la classe base ha un costruttore senza parametri la classe derivata richiama quello Se la classe base NON ha un costruttore senza parametri la classe derivata deve esplicitamente richiamarlo: super class Animale { Animale(int numeroZampe) { … } } class Pesce extends Animale{ Pesce() { super(0); } }
Overriding La classe derivata può riscrivere il comportamento di un metodo definito nella classe base class Animale { void respira() { … } } class Pesce extends Animale { void respira() { getBranchie().respira(); }
Binding dinamico Il codice da eseguire viene calcolato a run-time oggetti polimorfici/polimorfismo A run-time la variabile a è di tipo Squalo viene eseguito il metodo respira() della classe Squalo Animale a = new Squalo(); a.respira();
Protezione di accesso Una classe derivata può non aver bisogno di accedere a tutti i membri della classe base private : accessibile solo all’interno della classe default/package : accessibile all’interno del package protected : accessibile anche alle sottoclassi public : accessibile a tutti - attributo: tipo # attributo: tipo + attributo: tipo attributo: tipo
Classi astratte Una classe astratta ( abstract ) è una classe di cui non possono essere istanziati oggetti Possono essere istanziati oggetti solo delle sue sottoclassi Permette di definire un comportamento generale
Nell’esempio precedente Uccello vola(): void Pesce nuota(): void Animale respira(): void SqualoAquila
Abstract Una classe astratta può non voler definire tutti i metodi L’implementazione deve essere definita nelle classi concrete Una classe con almeno un metodo definito abstract e quindi non implementato deve essere dichiarata abstract abstract class Animale { abstract void respira(); }
Final Una classe final NON può essere derivata Un metodo final non può essere riscritto final class Squalo extends Pesce { … } class Pesce extends Animale { final int numeroZampe() { return 0; }
Casting Posso utilizzare oggetti delle classi derivate come fossero delle classi base Attenzione! Un Animale non può volare!! (non lo abbiamo definito) Aquila q = new Aquila(); Animale a = q; a.respira(); Aquila q = new Aquila(); Animale a = q; a.vola();
Casting Posso voler utilizzare un Animale come Aquila Adesso l’aquila può volare Animale a = new Aquila(); Aquila q = (Aquila) a; q.vola();
Casting Non si può trasformare un oggetto in un altro a piacimento Animale a = new Squalo(); Aquila q = (Aquila) a; q.vola();
Esercizi Individuare la gerarchia tra le seguenti classi Persona, Studente, Lavoratore, Docente Considerare, ove opportuno, gli attributi: nome, cognome, stipendio, data di nascita, altezza, materia, classe Disegnare il diagramma delle classi UML e implementare il codice Java
Esercizi Individuare la gerarchia tra le seguenti classi Quadrilatero, Rettangolo, Triangolo, Rombo Implementare il calcolo dell’area Disegnare il diagramma delle classi UML e implementare il codice Java
Esercizi abstract class Animale { abstract String getNome(); } class Gatto extends Animale { String getNome() { return "Gatto"; } } class Cane extends Animale { String getNome() { return "Cane"; } } public static void main(String[] args) { Animale a1 = new Cane(); Animale a2 = new Gatto(); a1 = a2; System.out.println(a1.getNome()); }