|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jan 2005
Città: Siena
Messaggi: 1313
|
[OOP] Ereditarietà multipla solo tramite interfacce... preché?
Ciao a tutti,
credo che sia noto a tutti che linguaggi come Java e C# non consentono l'ereditarietà multipla (tramite classi).... ma perchè? Capisco che potrebbe venir fuori un bel casino con i nomi delle variabili e metodi che potrebbero essere troppo simili (se non uguali) fra una classe madre e l'altra.... ma c'è altro? Qualcuno potrebbe fornirmi un link o indicarmi qualche libro da leggere che potrebbe chiarirmi le idee? O magari avete qualche esempio lampante? Thanks! ![]() Ultima modifica di astorcas : 12-02-2008 alle 16:29. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Il problema si chiama "Diamond Problem", ed e' parente del dubbio da te sollevato.
Immagina una classe A, padre di tutti, con il metodo virtuale Pippo(); B e C sono due altre classi figlie di A, ed entrambe implementano il metodo Pippo(), ma in modo diverso. Se poi D deriva da entrambe le classi B e C, essa e' ovviamente anche di tipo A, e pertanto avra' anch'essa il metodo Pippo. Ma se non effettua l'override di Pippo, qualora un'istanza di tale classe chiamasse il metodo, quale versione verrebbe eseguita? Se cerchi in giro lo trovi.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Jan 2005
Città: Siena
Messaggi: 1313
|
Quote:
|
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Infatti in caso di "conflitto" dev'essere il programmatore a "sbrogliare la matassa", indicando quale dei due metodi dev'essere chiamato.
![]() Comunque i "conflitti" dovuti a metodi con lo stesso nome possono verificarsi anche con le interfacce. ![]()
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
![]() |
![]() |
![]() |
#5 | ||
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Ci si puo' convivere, ma forzando il programmatore a specificare quale funzione usare tra quelle a disposizione e'un po' come avere delle funzioni esterne alla classe. Quote:
Le interfaccie sono solo dei contratti tra compilatore e programmatore, senza codice. Aggiungendo una interfaccia ad una classe solo si costringe tale classe ad avere implementati alcuni metodi particolari, e si potra' fare successivamente affidamento sull'esistenza di tali metodi. Se per un motivo o per l'altro l'implementazione del metodo dell'interfaccia la tua classe gia' ce l'ha (nel nostro caso appunto perche' l'ha erediata) tanto di meglio. Ma non si hanno conflitti. Codice:
class padre { public int pippo = 0; public virtual int MetodoCritico(int variabile) { return 0; } } interface HabemusCriticum { int MetodoCritico(int variabile); } class NonCentraNulla:HabemusCriticum { public int robadinoncentranulla=-1; #region HabemusCriticum Members public int MetodoCritico(int variabile) { throw new Exception("The method or operation is not implemented."); } #endregion } class figlio:padre,HabemusCriticum { public int altro = -1; public int AltroAncora(float ciccio) { return 0; } }
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
||
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Dec 2005
Messaggi: 7251
|
@gugoXX
e se due interfaccie hanno un metodo con lo stesso nome, stessi parametri, ma tipi di ritorno diversi? ![]() mi sa che il compilatore si offende in ogni caso, ma dovrei provare. in java bisogna stare attenti anche con la dichiarazione delle eccezioni. questo non toglie IMHO che ereditarietà singola + interfacce porta nella maggiorparte dei casi a soluzioni più eleganti e più semplici da comprendere. poi anche il compilatore può togliersi questo peso ![]() |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
PS. Ragassuoli, interfacce senza la i ![]()
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA Ultima modifica di fek : 13-02-2008 alle 09:53. |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Esistono situazioni come il virtual multiple dispatch, quando il dispach non e' solo sull'oggetto ma anche sugli argomenti del metodo, che possono essere risolti in maniera piu' semplice e elegante attraverso l'ereditarieta' multipla. Per fortuna sono rari e non me ne e' praticamente mai capitato uno per strada.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Se hai tempo potresti buttare giu' un paio di esempi?
Stavo cercando appunto un caso in cui l'eredita' multipla potesse avere vantaggi rispetto alle interfacce (senza la i), ma non me ne e' venuto in mente neppure uno che non riuscissi a risolvere comunque elegantemente con un buon disegno ad interfacce.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
A parte gli scherzi, si', cerco di buttare giu' un esempio ma mi devo ristudiare il problema prima, perche' l'ultima mi si e' arrotolato il cervello e non e' un design che si usa spesso. Ricordamelo pero'.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
Quote:
Codice:
public class MediaAritmetica { public double media(int x, int y) { ; } public float media(int x, int y) { ; } } |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2774
|
Credo che lui intendesse due interfacce distinte con ognuna un metodo con stesso nome e parametri ma tipo di ritorno diverso e poi una terza classe che le eredita
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Dec 2005
Messaggi: 7251
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Jan 2005
Città: Siena
Messaggi: 1313
|
Caspita mi avete illuminato!
Ma allora in caso di ereditarietà multipla (vedi C++) che cavolo fa il compilatore se una classe estende 2 classi aventi stesso metodo con comportamento completamente diverso? Bisogna specificare esplicitamente quale dei due utilizzare, si ha errore in compilazione o cos'altro? In effetti potrei provare da me.... |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Supponi di avere la seguente situazione Codice:
Robot / \ / \ / \ FlyingRobot GenericRobot \ / \ R2D2 HK-47 A me questo sembra un caso in cui tutte le alternative sembrano meno semplici e pulite.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
|
Quote:
Per inciso qualcuno conosce qualche linguaggio che supporti il multiple dispatch in modo "naturale", oltre a CLOS ? ![]()
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele |
|
![]() |
![]() |
![]() |
#18 | ||
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
![]()
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||
![]() |
![]() |
![]() |
#19 | ||
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
![]() Se non sono indiscreto, posso chiederti per cosa lo usate? ![]() Quote:
![]() ![]()
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Se hanno tipo di ritorno diverso sono due metodi diversi e sono illegali quindi il problema non si pone
![]() (Non in C++ se i due tipi di ritorno sono compatibili)
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:03.