L’ereditarietà
=>>>
RIASSUNTO CAPITOLO 3 PROGRAMMAZIONE LIBRO
Abbiamo già de,o che l’ereditarietà è uno dei conce6 chiave della programmazione
OO. Uno dei suoi obie6vi principali è quello di facilitare il riuso del so@ware;
fondamentalmente l’idea principale dell’ereditarietà è che una classe derivata erediC
le funzionalità di una classe base.
Questo è molto uCle perché consente di evitare la duplicazione del codice e, nel caso
bisogni modificare l’implementazione delle funzioni comuni nella classe base il
cambiamento viene ereditato automaCcamente nelle classi derivate.
Può succedere che una classe derivata funga da classe base per altri classi, formando
così una gerarchia di classi. Quindi più corre,amente si può dire che una classe
derivata “estende” le funzionalità di una classe base. Se una classe non fornisce
nessuna estensione allora probabilmente c’è un errore nel design della classe.
A livello sinta6co, l’ereditarietà in C++ è espressa aggiungendo nella dichiarazione
della classe derivata, dopo il suo nome, un “:” seguito da un livello di accesso e dal
nome della classe base da cui si eredita.
- 3.1.1: ereditarietà vs composizione
La scelta di usare l’ereditarietà o la composizione è essenzialmente una scelta di
design e dipende dal Cpo di relazione che si vuole modellare. Appunto, come già
de,o, non ci sono regole fisse nello scegliere l’uno o l’altro approccio.
Tu,avia, la composizione in alcuni casi può risultare uCle per modellare dei casi che
non sono o,enibili con l’ereditarietà; per esempio, quando si vogliono avere istanze
mulCple di una classe.
- 3.1.2: i livelli di accesso
I livelli di accesso nell’ereditarietà sono molto uCli perché consentono di definire
l’interfaccia di una classe, modificando il livello di accesso dei membri ereditaC dalla
classe base. Quindi avremo che:
1. Nel caso di una classe derivata in modo public o protected questa eredita i
membri pubblici e prote6 della classe base e li espone con tale livello di
accesso.
2. Nel caso di una classe derivata in modo private questa eredita i membri
pubblici e prote6 della classe base portandoli al livello private in modo da
non renderli fruibili al di fuori di essa.
Infa6, è da notare come i membri privaC di una classe rimangono sempre tali, per
cui una classe derivata non potrà mai accedervi sebbene vengano ereditaC.
Questa situazione è molto favorevole dato che manCene la proprietà di
incapsulamento. Quindi è buona norma avere daC membro privaC ma metodi
pubblici o prote6 così che se bisogna effe,uare delle modifiche non si va ad
intralciare il codice delle classi client.
Se vogliamo che i membri di una classe base siano visibili ai metodi di una classe
derivata e basta bisogna dichiararli prote6.
Se ovviamente si viene a formare una gerarchia di classi, tali membri rimarranno
prote6 all’interno della gerarchia a meno che l’ereditarietà non sia privata.
- 3.1.3: costru,ori e distru,ori
Nel caso venga creato un ogge,o in una classe derivata i costru,ori vengono invocaC
in maniera sequenziale fino ad arrivare al costru,ore della classe più derivata
formando, così, un processo di Cpo “bo,om-up”.
Viceversa, nel caso dei distru,ori quesC vengono sempre chiamaC in maniera
sequenziale ma si parte dal distru,ore della classe più derivata fino ad arrivare al
distru,ore della classe base formando un processo di Cpo “top-down”.
- 3.2: il principio di sosCtuzione di Liskov
Il seguente principio afferma che una gerarchia di classi è formata da so,o-Cpi e
super-Cpi; dunque, la sosCtuibilità rappresenta un principio della programmazione
OO che dice che:
“Se S è un so,o-Cpo di T allora gli ogge6 di Cpo T possono essere rimpiazzaC da
ogge6 di so,o-Cpo S senza alterare nessuna proprietà desiderabile del programma.”
In altre parole, se una classe derivata estende una classe base senza alterarne in
modo significaCvo il suo comportamento allora si può effe,uare la sosCtuzione e
tale principio risulta parCcolarmente uCle poiché perme,e di o,enere un buon
design di gerarchie di ereditarietà di classi.
Nel caso di ereditarietà pubblica, la sosCtuibilità è data dal fa,o che la classe
derivata espone ai suoi utenC tu,a l’interfaccia pubblica della classe base con lo
stesso livello di accesso.
Nel caso di ereditarietà privata, il comportamento è differente dato che la classe
derivata non è più un so,o-Cpo della classe base e quindi non sarà possibile usare
un ogge,o di Cpo derivato al posto di un ogge,o di Cpo base.
Quindi si usa l’ereditarietà privata se vogliamo ereditare l’implementazione della
classe base e quella pubblica se vogliamo ereditare anche l’interfaccia.
- 3.3: il pol
-
Appunti riassuntivi Programmazione (parte 1, linguaggio C++)
-
Appunti riassuntivi Programmazione (parte 6, adapter e observer)
-
Appunti riassuntivi Programmazione (parte 3, design OO e eccezioni)
-
Appunti riassuntivi Programmazione (parte 5, puntatori e design pattern)