# EreditarietÃ , so what? - era Re: \[?

**URL:** <https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200>\
**Category:** IT\
**Created:** [June 1, 2006, 12:53pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200 "2006-06-01T12:53:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chiaroscuro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@chiaroscuro](https://www.ruby-forum.com/u/chiaroscuro)\
**Post date:** [June 1, 2006, 12:53pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200/1 "2006-06-01T12:53:58Z")

</div>

On 6/1/06, Riko [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Io non direi proprio che se fa “quack” è una papera. Io direi che se fa  
> “quack” lo puoi trattare come una papera.
> 
> Dire che “è” una papera significherebbe lasciare intendere che un is\_a?  
> Duck darebbe true.

Interessante il disorso sull’ “essere” e sul “trattare come se”.

Più uso ruby, più tendo a delegittimare il valore dell’ essere/is\_a in  
favore del “trattare come”/respond\_to. Anche l’ereditarietà sembra in  
questo contesto perdere un pò di senso, e sto osservando il mio stile che  
di  
conseguenza tende a cambiare.

Voi cosa ne pensate? Qual’è il ruolo dell’ereditarietà in un linguaggio  
come ruby?

---

<div class="post-metadata">

**Author:** ![chiaroscuro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@chiaroscuro](https://www.ruby-forum.com/u/chiaroscuro)\
**Post date:** [June 1, 2006, 3:47pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200/2 "2006-06-01T15:47:21Z")

</div>

chiaro scuro wrote:

> Più uso ruby, più tendo a delegittimare il valore dell’ essere/is\_a in  
> favore del “trattare come”/respond\_to. Anche l’ereditarietà sembra in  
> questo contesto perdere un pò di senso, e sto osservando il mio stile  
> che di conseguenza tende a cambiare.

Io purtroppo non ho mai programmato in Smalltalk. Il contatto più  
diretto con Smalltalk lo ho avuto tramite ObjectiveC (sono macchista de  
fero) e appunto Ruby.

A questo proposito vorrei citare alcune righe (o forse una parafrasi,  
tiro fuori il libro, vedo quanto è lungo) da DP della GOF, libro appunto  
scritto con esempi in C++ e in Smalltalk.

In tutto il libro viene mantenuta la distinzione introdotta nel primo  
capitolo fra e classe.

"Il tipo è il nome usato per denotare una particolare interfaccia.  
Diciamo che un oggetto è di tipo Window se accetta tutte le richieste  
per le operazioni definite nell’interfaccia Window. Un oggetto può avere  
molti tipi e oggetti estremamente differenti condividere un tipo.  
Parte dell’interfaccia di un oggetto può essere caratterizzata da un  
tipo, e parte da un altro. Due oggetti dello stesso tipo hanno bisogno  
solamente di condividere parte delle loro interfacce.

Interfacce possono contenere altre interfacce come sottoinsiemi. Un  
tipo è un sottotipo di un altro oggetto se la sua interfaccia contiene  
l’interfaccia del suo sopratipo."  
(…)  
“L’implemenmtazione di un oggetto è definita dalla sua classe”.  
(…)  
È importante capire la differenza fra la classe di un oggetto e il suo  
tipo. La classe definisce come è stato implementato. Definisce il suo  
stato interno e l’implementazione delle sue operazioni. D’altra parte il  
tipo di un oggetto si riferisce solo alla sua interfaccia, all’insieme  
di richieste a cui può rispondere. Un oggetto può avere molti tipi e  
oggetti di classi differenti possono avere lo stesso tipo

Naturalmente c’è una una stretta parentela fra classe e tipo. Poichè una  
classe definisce le operazioni che un oggetto è in grado di eseguire,  
definisce anche il suo tipo. Quando diciamo che un oggetto è un’istanza  
di una classe, diciamo implicitamente che l’oggetto supporta  
l’interfaccia definita dalla classe.

Linguaggi come C++ e Eifell (e Java ndt) usano le classi per specificare  
sia il tipo di un oggetto che la sua implementazione.  
".

[http://www.akropolix.net/rik0/blogs/2006/06/01/sul-duck-typing-ruby-python-etc/](http://www.akropolix.net/rik0/blogs/2006/06/01/sul-duck-typing-ruby-python-etc/)

> Voi cosa ne pensate? Qual’è il ruolo dell’ereditarietà in un linguaggio  
> come ruby?

Per me l’ereditarietà è in primo luogo una questione di DRY,

–  
blog: [http://www.akropolix.net/rik0/blogs](http://www.akropolix.net/rik0/blogs) |  
site: [http://www.akropolix.net/rik0/](http://www.akropolix.net/rik0/) |  
forum: [http://www.akropolix.net/forum/](http://www.akropolix.net/forum/) |

---

<div class="post-metadata">

**Author:** ![chiaroscuro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@chiaroscuro](https://www.ruby-forum.com/u/chiaroscuro)\
**Post date:** [June 1, 2006, 3:47pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200/3 "2006-06-01T15:47:22Z")

</div>

chiaro scuro wrote:

> Interessante il disorso sull’ “essere” e sul “trattare come se”.
> 
> Più uso ruby, più tendo a delegittimare il valore dell’ essere/is\_a in  
> favore del “trattare come”/respond\_to. Anche l’ereditarietà sembra in  
> questo contesto perdere un pò di senso, e sto osservando il mio stile  
> che di conseguenza tende a cambiare.
> 
> Voi cosa ne pensate? Qual’è il ruolo dell’ereditarietà in un linguaggio  
> come ruby?

Dicevo… .per me è una questione di DRY al 90% l’ereditarietà (oltre che  
nel caso di modellare la realtà esistente).

Mah… qua è partito un flash di riflessioni un po’ confuse ma corpose:

In tempi di Duck Typing ridiventa certamente di moda la distinzione  
fra classi e tipi che si trova per esempio nel capitolo introduttivo di  
Design Patterns di Gamma, Helm, Johnson e Vlissides.

La maggior parte delle persone sono oggi abituate a linguaggi come  
Java o C++ dove classi e tipi in buona sostanza coincidono (con la  
possibile eccezione della programmazione generica).

Un tipo è il nome usato per denotare una particolare interfaccia.  
Questo non ha direttamente a che vedere con le Interfaces del Java, per  
inciso. L’interfaccia è l’insieme di metodi (o di messaggi, per dirla  
con Ruby, Smalltalk o ObjectiveC) cui un oggetto risponde.

Tuttavia un oggetto può implementare diversi tipi, e tipi diversi  
possono essere condivisi da oggetti molto diversi fra loro. In questo i  
tipi si comportano come le interfacce Java. Qualunque programmatore Java  
sa che ci sono Interfacce (uso il maiuscolo per indicare che intendo la  
parola nel senso “Javesco”) supportate da diversi oggetti (leggi  
Cloneable, per esempio) e che un qualunque oggetto può implementare un  
numero grande a piacere di Interfacce.

La differenza è che le Interfacce di Java sono statiche e “legate”  
alle classi. Una data classe dice di implementare un certo numero di  
interfacce. Le istanze di quella classe avranno quindi per tipo le varie  
interfacce.  
In Ruby tuttavia questo non accade. Un oggetto ha un dato tipo perché  
risponde a determinati messaggi, ma non specifichiamo da nessuna parte  
quale sia il tipo. Per il solo fatto di rispondere a certi messaggi un  
oggetto è di un dato tipo (a prescindere dalla sua classe). I tipi sono  
“informali” (usando la stessa differenza fra protocolli formali e  
informali di ObjectiveC – i protocolli formali si comportano  
sostanzialmente in modo simile alle Interfacce di Java, quelli informali  
sono appunti “non staticamente tipizzati”).

La classe è invece legata direttamente all’implementazione. Citando DP  
del GOF  
"È importante capire la differenza fra la classe di un oggetto e il  
suo tipo. La classe definisce come è stato implementato. Definisce il  
suo stato interno e l’implementazione delle sue operazioni. D’altra  
parte il tipo di un oggetto si riferisce solo alla sua interfaccia,  
all’insieme di richieste a cui può rispondere. Un oggetto può avere  
molti tipi e oggetti di classi differenti possono avere lo stesso tipo

Naturalmente c’è una una stretta parentela fra classe e tipo. Poiché  
una classe definisce le operazioni che un oggetto è in grado di  
eseguire, definisce anche il suo tipo. Quando diciamo che un oggetto è  
un’istanza di una classe, diciamo implicitamente che l’oggetto supporta  
l’interfaccia definita dalla classe.

Linguaggi come C++ e Eifell (e Java ndt) usano le classi per  
specificare  
sia il tipo di un oggetto che la sua implementazione"

D’altra parte linguaggi dinamici come Ruby o Python (o Smalltalk) non  
dichiarano i tipi delle variabili. Mandano messaggi (o chiamano metodi,  
per dirla con Python) agli oggetti denotati dalle variabili e se tali  
oggetti supportano il messaggio, tutto  
funzionerà.  
La differenza fra ereditarietà di classe e ereditarietà di tipo è  
importante. L’ereditarietà di classe riguarda definire l’implementazione  
di un oggetto attraverso l’implementazione di un altro oggetto. È senza  
dubbio un concetto “DRY”. Se ho già definito delle cose (e gli oggetti  
sono sufficientemente vicini) posso mantenerle uguali. In Ruby a questo  
si associano i mixin che permettono di condividere codice _senza_ andare  
in ereditarietà (ma questa è un’altra storia), in Python si può usare  
l’ereditarietà multipla per emulare i mixin.

L’ereditarietà di tipo è invece relativa all’utilizzare un oggetto al  
posto di un altro. In questo senso siamo più vicini al Principio di  
Sostituzione di Barbara Liskov. Un ottimo articolo relativo al LSP si  
trova qui ([Vacation Rental Hacks](http://www.objectmentor.com/resources/articles/lsp.pdf)). In  
buona sostanza possiamo enunciare il Principio di Sostituzione di Liskov  
come:

T1 è un sottotipo di T2 se per ogni oggetto O1 di tipo T1 esiste un  
oggetto O2 di tipo T2 tale che per ogni programma definito in termini di  
T1 il comportamento del programma è invariato sostituendo O2 al posto di  
O1.

Confondere ereditarietà di tipo e di classe è facile. Molti linguaggi  
non hanno alcuna distinzione fra le due. Anzi, vengono usate le classi  
per definire i tipi. Molti programmatori per esempio vedono il LSP solo  
in relazione alle sottoclassi (in effetti in C++ è importante fare in  
modo tale che gli oggetti si comportino “bene” in relazione al LSP, in  
quanto è sempre possibile fare puntare un puntatore o una reference di  
un supertipo ad un oggetto del suo sottotipo).

In realtà il principio di Liskov è una cosa _molto_ severa. Due  
oggetti sono sostituibili secondo Liskov se davvero (limitatamente al  
tipo comune) si comportano allo stesso modo, e viene naturale pensarli  
come classe - sottoclasse (anche se effettivamente questo _non_ è  
necessario).  
Il DuckTyping è meno severo: non chiede che il programma abbia lo  
stesso comportamento. Due oggetti sono appunto sostituibili se  
rispondono alle stesse cose, anche se rispondono in modo diverso. Non ha  
_nulla_ a che fare con il Design By Contract: è molto più vicino a  
quello che in C++ si fa con i templates (che alcuni in effetti vedono  
come il corrispettivo statico del Duck Typing).

Tornando a noi, se un oggetto si comporta secondo un certo tipo  
(ovvero risponde ai metodi propri di quel tipo), allora trattiamolo come  
tale. Da cui: se si comporta come una papera, trattiamolo come una  
papera (Duck Typing, appunto).

Un linguaggio come Ruby rende _molto_ problematico considerare come  
stretta la relazione fra tipi e classi. In ogni punto del programma  
(anche se non è sempre buona pratica farlo) possiamo cambiare il tipo di  
tutti gli oggetti di una data classe (aggiungendo o togliendo metodi  
alla stessa), o singolarmente ad un singolo oggetto. Sintomatico è in  
questo senso avere deprecato il metodo Object#type in favore di  
Object#class.

–  
blog: [http://www.akropolix.net/rik0/blogs](http://www.akropolix.net/rik0/blogs) | Enrico F.  
site: [http://www.akropolix.net/rik0/](http://www.akropolix.net/rik0/) | RiK0  
forum: [http://www.akropolix.net/forum/](http://www.akropolix.net/forum/) | Usenet: removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![chiaroscuro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@chiaroscuro](https://www.ruby-forum.com/u/chiaroscuro)\
**Post date:** [June 2, 2006, 2:10pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200/4 "2006-06-02T14:10:25Z")

</div>

Mi hai steso 🙂 Stavo per dirti di postarla su un blog, ma vedo che  
hai  
già fatto.

Ma dimmi, allora 'sta ereditarietà… la usiamo solo come meccanismo per  
non  
ripetere implementazione e per non sbatterci a fare delegation? Perchè non  
usare solo mixin e delegation e delle pure interfaces (dichiarazioni di  
metodi/respond\_to) da poter dichiarare come contratto su alcuni  
argomenti  
dei metodi?

L’ereditarietà ci rimane allora solo come una ‘sporca’? un modo  
conveniente  
di poter dire queste cose (riutillizzo implementazione, delegation,  
dichiarazione di supporto di certi metodi) in modo rapido? Esistono  
altri  
modi convenienti di dire cose che sono ortogonali  
all’ereditarietà?  
PS: è una provocazione, non datemi addosso e proviamo a vedere dove ci  
conduce questo pensiero

On 6/1/06, Riko [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> chiaro scuro wrote:
> 
> Dicevo… .per me è una questione di DRY al 90% l’ereditarietà (oltre che  
> nel caso di modellare la realtà esistente).
> 
> Mah… qua è partito un flash di riflessioni un po’ confuse ma corpose:

## – Chiaroscuro

Liquid Development: [http://liquiddevelopment.blogspot.com/](http://liquiddevelopment.blogspot.com/)

---

<div class="post-metadata">

**Author:** ![chiaroscuro](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@chiaroscuro](https://www.ruby-forum.com/u/chiaroscuro)\
**Post date:** [June 2, 2006, 5:45pm UTC](https://www.ruby-forum.com/t/ereditarieta-so-what-era-re/62200/5 "2006-06-02T17:45:17Z")

</div>

chiaro scuro wrote:

> Mi hai steso 🙂 Stavo per dirti di postarla su un blog, ma vedo che hai  
> già fatto.

Si beh… in realtà prima mi sarebbe anche piaciuto se in lista se ne  
fosse parlato un poco. Nel senso che era una bozzettona, l’ho messa su  
tanto per me, ma imho lavorandoci su un poco sarebbe venuta fuori una  
bella cosa sgrezzata.

> Ma dimmi, allora 'sta ereditarietà… la usiamo solo come meccanismo per non  
> ripetere implementazione e per non sbatterci a fare delegation? Perchè non  
> usare solo mixin e delegation e delle pure interfaces (dichiarazioni di  
> metodi/respond\_to) da poter dichiarare come contratto su alcuni argomenti  
> dei metodi?

Credo per ragioni di praticità. Quando in effetti il modello “reale” ha  
ereditarietà non vedo perchè non usarla (a parte i casi particolari,  
tipo il quadrato e il rettangolo).

Credo che tutte le “regole” rigide falliscano in un numero non  
trascurabile di casi. Meglio essere flessibili: capire che  
l’ereditarietà non va usata sempre (e davvero, è difficile pensarci in  
certi linguaggi… parecchi guru hanno dovuto dire la loro per esempio  
per spiegare che certe catene di ereditarietà erano _troppo_ lunghe).

> L’ereditarietà ci rimane allora solo come una ‘sporca’? un modo conveniente  
> di poter dire queste cose (riutillizzo implementazione, delegation,  
> dichiarazione di supporto di certi metodi) in modo rapido? Esistono altri  
> modi convenienti di dire cose che sono ortogonali all’ereditarietà?

IMHO bisogna soprattutto sfatare il mito che la programmazione ad  
oggetti “is about inheritance”. E poi comunque resta il fatto che  
l’ereditarietà di sottotipo è comunque molto importante.

Quindi l’obiezione sarebbe soprattutto sull’ereditarietà di classe. Ma  
anche li, dopo tutto… a patto di non esagerare.  
Altro esempio classico è fare ereditare un aereo da un motore. In fondo  
con un po’ di buon senso, tenendo presente se effettivamente le  
relazioni reali sono is\_a has\_a o altro ancora, ce la si può cavare.

–  
blog: [http://www.akropolix.net/rik0/blogs](http://www.akropolix.net/rik0/blogs) | Enrico F.  
site: [http://www.akropolix.net/rik0/](http://www.akropolix.net/rik0/) | RiK0  
forum: [http://www.akropolix.net/forum/](http://www.akropolix.net/forum/) | Usenet: removed\_email\_address@domain.invalid
