Newsgroup: it.comp.java
Titolo: Java teoria: ereditarietà multipla e singola

Premessa
----------
Sono alle prime armi con questo splendido linguaggio, conosco il C ed il C++
quindi mi è sembrato
utile estendere le nozioni sulla programmazione con questo linguaggio avente
la caratteristica fondamentale della portabilità fra differenti piattaforme.
Domanda
----------
Studiando sul libro Java Mattone dopo Mattone, al capitolo 6 dove si tratta
dell'ereditarietà, si
afferma che Java è un linguaggio che supporta il meccanismo
dell'ereditarietà singola, in sostanza
da una classe base o superclasse è possibile derivare (o estendere) una sola
classe derivata.
Nel C++ è possibile derivare una classe da diverse superclassi
contemporaneamente utilizzando
la sintassi
class classe-derivata : classe-base1, classe-base2
{
 ....
}
in Java è possibile derivare classi solo da una superclasse scrivendo:
specificatorediclasse class NomeClasseDerivata extends NomeClasseBase
{
}
La questione che mi sono posto è la seguente, da un punto di vista teorico
io posso ancora estendere la classe derivata NomeClasseDerivata da un'altra
superclasse, quindi, di fatti, avrei una classe che suporta
membri e metodi delle due superclassi. In sostanza ho ottenuto un risultato,
mi sembra di capire, analogo
a quello che avrei ottenuto in C++ con un unico formalismo.
A questo punto, se ho interpretato correttamente le cose, come mai anche in
Java non è stato
previsto un meccanismo di ereditarietà multipla come nel C++? Lo stesso
oggetto si ottiene applicando due volte il costrutto extends, sarebbe quindi
solo ridondante?
Grazie a chiunque vorrà rispondere ad un novellino e ad un quesito forse di
dubbia importanza (almeno dal punto di vista pratico).
Ciao
Pow
--
----------------------------------------------------
Ama il tuo mestiere con passione
E' il significato della tua vita
Auguste Rodin (1840-1917)
 "Not everything that  counts can be
 counted, and not everything that can
be counted counts".
Albert Einstein
"Hunt for the Engineer and the Engineer will hunt you."
Hellraiser5 Pinhead

 Hellraiser5 Pinhead
-- 
Those who don't understand unix are condemned to reinvent it. Poorly.
(H.Spencer)
Alex 'Kazuma' Garbagnati
EJB & Tomcat jGuru FAQ Manager, 
http://www.jguru.com
Tutor "Progetto Scuole" 
http://www.jia.it
Java Italian Association, Sun, Ministero Istruzione Universita' Ricerca
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 dubbia importanza (almeno dal punto di vista pratico).




  // altro codice
}



  // altro codice
}


  // altro codice
}


  // altro codice
}

public myTest {


    figlio.famiglia();
    // resto del codice...
}
Domanda... che cosa otterro'?
E' probabile che questa mia visione sia pessimistica e che magari la
scelta di non implementare l'ereditarieta' multipla sia dovuta ad altri
arcani, ma leggendo una whitepaper scritta da Gosling e McGilton nel 1996,
mi sono fatto questa idea.
Se vuoi, magari puoi dargli una occhiata e magari confutare o meno la mia
idea. (anzi, invito tutti a farlo... sono qui per imparare anche io.):
The Java Language Environment: 
http://java.sun.com/docs/white/langenv/
Regards,
Kazuma


Il messaggio a cui sto rispondendo e' un errore. Ho premuto invio al
momento sbagliato...
Mi scuso del casino.
regards,
Kazuma


 membri e metodi delle due superclassi. 
Non ho capito che vuoi dire, potresti fare un esempio?
Grazie
Ciao
Matteo

 dubbia importanza (almeno dal punto di vista pratico).
Essere un novellino non c'entra: qui si e' tutti per imparare e cercare di
aiutare gli altri. Inoltre, come ha gia' rilevato Kazuma, il quesito non
e' affatto di dubbia importanza, ne' dal punto di vista pratico, ne' dal
punto di vista teorico.
Da qualche parte mi sembrava di aver letto che c'e' almeno un caso in cui
in effetti l'ereditarieta' multipla sarebbe indispensabile e permette di
risolvere piu' elegantemente il problema di quanto si possa fare con il
meccanismo delle interfacce, ma ora non ricordo ne' dove l'ho letto, ne
quale e' questo caso. Qualcuno puo' rinfrescarmi la memoria? O me lo sono
sognato?
-- 
Lucio Benfante - Java User Group Padova
Brainbench MVP for Java 1
http://www.brainbench.com
MyTranscript: 
http://www.brainbench.com/transcript.jsp?pid=167064

 ha scritto nel messaggio
news:pan.2003.06.07....@mailandnews.com...


 punto di vista teorico.
Grazie per il supporto sia a Kazuma che a Lucio per le spiegazioni, mi
piacerebbe comunque
continuare nell'approfondire la questione, se la cosa non vi secca sono
sempre qua a braccia aperte ;-)
Visto che sicuramente la sepete più lunga di me è l'esperienza in questo
linguaggio non vi manca, ho compratoil libro di Ivor Horton "JAVA2 SDK 1.4
Edition guida per il programmatore" edito dalla Apogeo.
Avete avuto l'occasione di leggerlo, mi potete dare un vs parere?
Grazie ancora per la vs assistenza ed il prezioso aiuto


 ha scritto nel messaggio
news:bbt491$53j$1...@news.newsland.it...

Molto interessante, in sostanza se si considera la catena dell'ereditarietà
ottengo una redifinizione del metodo
famiglia(), quindi suppongo che la mia attenzione debba concentrarsi sul
fatto "cosa eseguirà il compilatore richiamando
il metodo famiglia?", in altre parole, se io fossi il compilatore, avrei
un'ambiguità legata al fatto che non so quale metodo eseguire, a meno
di non specificarlo esplicitamente, ad esempio:
figlio.PADRE.NONNO.famiglia()
E' giusto?
Saluti


 da 2 o + classi completamente slegate fra loro. un'ereditą come la tua a +
[CUT]
Grazie anche a te per la risposta.


Pow
	Saluti a te...
	Regards,
		Kazuma
---
I've got nothing against God. It's his fan club I can't stand.
Alex "Kazuma" Garbagnati, 
http://www.kazuma.net
EJB & Tomcat jGuru FAQ Manager, 
http://www.jGuru.com
Tutor "Progetto Scuole", 
http://www.JIA.it
Java Italian Association - SUN - MIUR

Pow
De Nada.
	regards,


 ha scritto nel messaggio
news:_3pEa.13875$Fr5.2...@tornado.fastwebnet.it...

Problema iniziale
-----------------
Immagina di avere due classi una denominata PrimaClasse ed una
SecondaClasse, queste due classi
contengono un certo numero di variabili membro e di metodi che vorrei avere
tutti disponibili all'interno
di una stessa classe.
Ipotesi 1
---------
Si supponga di avere disponibile il codice sorgente di entrambe le classi.
Dimostrazione
--------------
Per ottenere questo potrei sfruttare l'ereditarietà multipla in C++ oppure
fare due livelli di ereditarietà singola con Java quindi:
class PrimaClasse
{
 // ...
}
class SecondaClasse extends PrimaClasse
{
 // Ho tutte le variabili membro ed i metodi definiti in PrimaClasse
 // con in più le variabili membro ed i metodi definiti in SecondaClasse
}
Ipotesi 2
---------
Ipotizziamo di conoscere i metodi esposti da due classi denominate
PrimaClasse e SecondaClasse
in cui il codice sorgente di una delle due classi od entrambe non risulta
disponibile, in questo caso
come faccio ad ottenere con Java una classe denominata TerzaClasse che
contenga le variabili membro e di metodi
sia di PrimaClasse sia di SecondaClasse?
Se scrivessi:
class TerzaClasse extends PrimaClasse
{
 // Ho tutte le variabili membro ed i metodi definiti in PrimaClasse
 // ma non ho ancora le variabili membro ed i metodi definiti in
// SecondaClasse
}
come faccio ad includere in TerzaClasse anche le variabili membro ed i
metodi disponibili in PrimaClasse?
Potrei forse scrivere:
class PrimaClasse
 {
  public PrimaClasse()
   {
    System.out.println("Costruttore di PrimaClasse");
   }
  public void NomeClasse()
   {
    System.out.println("Metodo NomeClasse di PrimaClasse");
   }
 }
class SecondaClasse
 {
  public SecondaClasse()
   {
    System.out.println("Costruttore di SecondaClasse");
   }
  public void NomeClasse()
   {
    System.out.println("Metodo NomeClasse di SecondaClasse");
   }
 }
class TerzaClasse extends PrimaClasse
 {
  SecondaClasse QuartaClasse = new SecondaClasse();
  public TerzaClasse()
   {
     System.out.println("Costruttore di TerzaClasse");
   }
 }
 class SimpleApp
  {
   public static void main(String args[])
    {
     TerzaClasse MyTerzaClasse = new TerzaClasse();
     MyTerzaClasse.NomeClasse();
     MyTerzaClasse.QuartaClasse.NomeClasse();
    }
  }
però non è l'idea originale di ottenere una classe, in questo caso
TerzaClasse contiene un oggetto di tipo SecondaClasse, mentre
io vorrei avere incluso in TerzaClasse anche SecondaClasse e non una sua
istanza.



Grazie 100000!!!!
Questo significa che lo studio procede nel verso giusto, ancora grazie per
la preziosa assistenza,
spero di poter contraccambiare in futuro!
Ciao


 Poi, dopo che lo hai letto, fammi sapere che ne pensi tu !
Non mancherň, grazie per le info.
Ciao


 la stessa cosa?
Calma! Per i metodi, una classe eredita solo e esattamente i metodi del
padre, non delle classi 'nonno'; con l'eredità multipla se due metodi
sono in conflitto devi esplicitare quale erediti, con la singola invece
ottieni quello del padre.
Per le variabili, invece, il discorso alla fine è simile, ma non
raggruppare le due cose: nel senso che una classe eredita sempre quelle
del padre, ma non puoi fare un override di una variabile(ottieni un'altra
variabile con lo stesso nome, ma diversa).
Inoltre, se upcasti, si vede la differenza: se C deriva da A e da B e
casti C ad A, poi non è così chiaro per il compilatore che possa essere
castato a B(questo 'non è così chiaro' forse significa un warning o forse
che serve un reinterpret_cast, ma non ne ho idea); mentre invece se
C deriva da A che deriva da B, allora C, castata ad A, può tranquillamente
essere castata a B.
Ciao
-- 
cat <<EOSIGN
Paolo Giarrusso, aka Blaisorblade(togliere solo REMOVEONLYTHIS per rispondere)
Kernel 2.4.20/2.5.63 on an i686; Linux registered user n. 292729
EOSIGN


Anche a te il mio ringraziamento per la spiegazione, grazie 1000 per la
preziosa collaborazione.
Ciao a presto


 padre, non delle classi 'nonno'; 
Questo temo che non sia vero. Una classe eredita i metodi di tutte le classi
sopra di lei fino ad Object compresa.
Ciao
Matteo

 istanza.
Per i metodi ovviamente ci sono le interfacce, mentre per le variabile non
di istanza in Java non è possibile. L'unico modo è definire un'altra classe
in cui campi e metodi siano l'unione di quelli delle altre due ed estendere
questa.
Questo è anche il problema che si incontra passando da UML (in cui è
prevista l'ereditarietà multipla) a Java.
Stratagemmi come fare in modo che Seconda estenda Prima e Terza estenda
Seconda, funzionano ma probabilmente portano ad errori nella semantica
dell'ereditarità. Ricordiamoci sempre che A extends B significa "A è un B".
Se la cosa puo' avere un piccolo impatto in pratica ne ha uno molto grosso
sulla qualità complessiva del software la cui modularizzazione e
realizzazione in classi deve essere fatta secondo concetti un gradino più
in alto dell'avere certi metodi disponibili, e dipendenti dalla realtà da
modellare.
Ciao
Matteo

 Temo che sia impossibile.
Sospettavo.
Ciao e grazie



Io l'ho letto in parte e mi lo trovo molto buono.
In particolare la parte su XML e la stampa, ma sono
rimasto un po' male per la mancanza di un capitolo sui
database.
Ciao.










Chiedo scusa a tutti.
Maledetto OE!
Un saluto

 sorgente.
[cut]
No, per scrivere una classe che eredita da un'altra in Java non c'e'
bisogno del codice sorgente (nemmeno di una qualche forma di header), ma
solo della classe compilata (il .class ,per capirci).


java NON consente ereditarietà multipla in nessun modo, perché, come dici
tu, per estendere ulteriormente la classe NomeClasseDerivata, dovresti
obbligatoriamente copiarla in un altro oggetto e poi estenderla, il che non
sarebbe un'ereditarietà multipla vera. Se provi invece a inserire due
clausole extends, il compilatore protesterà, e anche parecchio.
Il motivo per cui è stata scelta questa strada lo trovi nelle origini di
java. Da una parte c'è stato il desiderio, dei progettisti del linguaggio,
di matenerlo semplice per un discorso di efficienza, ma oltre a questo, c'è
stata anche un'intensa fase di sviluppo di hardware. Java infatti è stato
progettato per essere digeribile direttamente dall'hardware quasi come
l'assembler. In pratica lo scopo è stato quello di fare una versione mooolto
più potente e flessibile dell'assembler tradizionale per determinate classi
di prodotti. All'inizio era stata la stessa Sun a presentare i progetti di
tre processori in grado di eseguire in hardware codice java, e a lei si sono
attaccati cani e porci... se hai un telefono Nokia, forse ti interesserà
sapere che non hai in mano nient'altro che un esecutore java, e come nokia
hanno fatto moltissimi altri...

In molti hanno già spiegato perche' Java non supporta l'ereditarieta' 
multipla (cioe' principalmente per mantenere la semplicita' nell'uso 
dell'ereditarieta').
Quello che voglio aggiungere io e' che questo non limita affatto le 
potenzialita' del linguaggio in quanto lo stesso scopo e' ottenibile 
(anche se con un po' di codice in piu') con un'altra strada.
Si tratta dell'uso delle interfacce piu' la "delegation".
Facciamo un esempio, Vogliamo ottenere in Java un equivalente del 
seguente codice C++ (scusate se faccio qualche errore ma e' un po' che 
non uso piu' questo linguaggio):
class base1 {
    protected int attributo1;
    public void metodo1(){ /*...*/ }
    public void metodo2(){ /*...*/ }
    /* ... */
}
class base2 {
    protected int attributo1;
    protected int attributo2;
    public void metodo2(){ /*...*/ }
    public void metodo3(){ /*...*/ }
}
class classe-derivata: base1, base2{
/*...*/
}
In Java possiamo procedere aggiungendo un'interfaccia nel seguente modo:
Class Base1 {
    protected int attributo1;
    public void metodo1(){ /*...*/ }
    public void metodo2(){ /*...*/ }
    /* ... */
}
class IntBase2 {
    public void metodo2();
    public void metodo3();
}
class Base2 implements IntBase2 {
    protected int attributo1;
    protected int attributo2;
    public void metodo2(){ /*...*/ }
    public void metodo3(){ /*...*/ }
}
class ClasseDerivata extends Base1 implements IntBase2 {
    protected IntBase2 implBase2 = new Base2(...);
    public void metodo3(){ implBase2.metodo3() } /* delegation */
}
Ci sono alcune differenze nel risultato finale. Cosi' come ho scritto 
non si puo' accedere a Base2.metodo2() tramite la classe ClasseDerivata.
I metodi di ClasseDerivata non possono accedere agli attributi protected 
di Base2, come avveniva invece in C++.
Pero' questi sono tutti ostacoli aggirabili. Diverso tempo fa (non ho il 
riferimento quindi) ho letto un articolo che sosteneva l'equivalenza 
espressiva tra ereditarieta' multipla di implementazione (quella del 
C++) e ereditarieta' multipla di interfaccia (quella di Java) abbinando 
quest'ultima al meccanismo della delegation.
Tra l'altro l'uso principale dell'eridarieta' non dovrebbe essere quello 
di riutilizzare l'implementazione (cosa che si puo' fare con la 
delegation andando incontro a minori problemi) ma quello di ottenere il 
polimorfismo. Per questo scopo le interfaccie sono perfette.
Andrea Polci


Ops è vero, infatti se so i metodi implementati in una classe di nome
ClasseEsterna e voglio derivare una classe che la specializzi di nome
MiaClasse
utilizzo extends applicato a ClasseEsterna, quindi:
class MiaClasse extends ClasseEsterna
{
 // Codice che specializza ClasseEsterna
}
quello che intedevo in realtà, colpa mia che non mi sono espresso in modo
rigoroso, mi riferivo al discorso fatto nei post passati in merito
al fatto di aggiungere il codice ad una classe preesistente, cosa orrenda
;-) dal punto di vista della portabilità verso altro utenti che già
utilizzano la classe originaria.
Grazie


 ha scritto nel messaggio
news:bc0gtc$f8f$1...@lacerta.tiscalinet.it...

Grazie per l'interessamento!!!!
Ciao


 obbligatoriamente copiarla in un altro oggetto e poi estenderla, il che
non
[CUT]
HE HE HE ... mi hai letto nel pensiero
si ho il Nokia, infatti sto già smanettando con le Midlet e JME.
Grazie anche a te per la spiegazione!!!


}
visto che IntBase 2 è un'interfaccia non dovrei dichiararla come segue:
interface IntBase2 {
    public void metodo2();
    public void metodo3();
}
utilizzando la parola chiave interface al posto di class?
Grazie ancora per l'esempio e la spiegazione dettagliata e completa,
continuerò nello studio del linguaggio
approfondendo il discorso.
Grazie ancora per l'intervento!
