L’ereditarietà è una delle caratteristiche più importanti che contraddistinguono la Programmazione Object Oriented (OOP) e senza alcun dubbio è anche la caratteristica più usata e “trasparente“.
Con questo articolo vorrei approfondire l’argomento per tutti quelli che si stanno avvicinando al linguaggio Java per la prima volta, ma le nozioni di cui vado a parlare sono valide per qualunque altro linguaggio che faccia uso degli oggetti. Questo significa che, a prescindere dal linguaggio utilizzato per programmare, in questo articolo verranno date nozioni generali sull’ereditarietà. Gli esempi saranno comunque scritti in Java, ma la filosofia non è vincolante.
Cominciamo con la definizione di ereditarietà: l’ereditarietà è la caratteristica per la quale un oggetto di classe B (detta classe derivata) che deriva da A (detta classe madre) possiede tutte le caratteristiche della classe madre.
Questa definizione sembra banale e riduttiva, ma non lo è: affermare che un oggetto B possiede tutte le caratteristiche di A, infatti, significa affermare che l’oggetto B è anche un oggetto di tipo A. Cerchiamo di spiegarlo con un esempio terra terra, che ci deriva dalla geometria piana. Tutti noi abbiamo in testa il concetto di Figura. Quando parliamo di Triangoli, Rettangoli e Cerchi tutti noi facciamo riferimento a delle figure. Questo ci suggerisce un legame tra questi concetti: un Triangolo è una Figura, un Rettangolo è una Figura, un Cerchio è una Figura. Tradotto in termini informatici, possiamo affermare che la classe Triangolo deriva dalla classe Figura, e via dicendo per le altre. Il termine tecnico (e inglese) con cui viene evidenziato questo legame è proprio “is-a” (cioè “è un”). Vediamo con del codice Java come si concretizza questo fatto:
public abstract class Figura {
public abstract int calcolaArea();
public void chiSono() { System.out.println("Sono una figura"); }
}
public class Triangolo extends Figura {
private int base;
private int altezza;
public Triangolo() { this(3, 4); }
public Triangolo(int base, int altezza) {
this.base = base;
this.altezza = altezza;
}
public int calcolaArea() { return (base * altezza) / 2; }
}
Tralasciamo per il momento il modificatore abstract che verrà approfondito in un prossimo articolo. Possiamo osservare che l’ereditarietà avviene tramite la parola chiave extends. Con questa “istruzione” andiamo a dire che la classe Triangolo estende per ereditarietà la classe Figura e, di conseguenza, ne eredita tutte le proprietà. Conseguentemente, la classe Triangolo possiede già, per costruzione, i due metodi calcolaArea() e chiSono() (perchè venga ridefinito, poi, il metodo calcolaArea() sarà argomento dello stesso articolo in cui si parlerà del modificatore abstract). Se richiamiamo, quindi, il metodo chiSono() su un oggetto di tipo Triangolo, non otterremo alcun errore e l’esecuzione produrrà la scritta a video “Sono una figura“. E questo risultato non può sorprenderci: un Triangolo, infatti, è una Figura.
Possiamo anche spingerci un po’ oltre e cercare di caratterizzare prima la figura Rettangolo e, subito dopo, specializzarla nella classe Quadrato: in questo modo un Rettangolo sarà una Figura e un Quadrato sarà un Rettangolo (un quadrato, infatti, è una forma particolare di rettangolo). Vediamolo con il codice:
public class Rettangolo extends Figura {
private int base;
private int altezza;
public Rettangolo() { this(0, 0); }
public Rettangolo(int base, int altezza) {
this.base = base;
this.altezza = altezza;
}
public int calcolaArea() { return (base * altezza); }
public int getBase() { return base; }
public int getAltezza() { return altezza; }
}
public class Quadrato extends Rettangolo {
public Quadrato() { super(0, 0); }
public Quadrato(int lato) { super(lato, lato); }
public int getLato() { return getBase(); }
}
Cosa si può dire ora della classe Quadrato? Facile: si può dire che è un Rettangolo, visto che la estende come classe. Ma si può dire anche di più: un Quadrato è una Figura. Non solo concettualmente, ma anche nella pratica informatica: Quadrato è sulla stessa linea di derivazione di Figura (Figura è la classe “nonna”), quindi è anche una Figura. Con questo aggiungiamo un tassello alla teoria: un oggetto di classe X è anche oggetto di ogni classe della sua linea di derivazione.
Una cosa importante da tenere in considerazione è che in Java una classe può ereditare al massimo da una sola classe; in altri linguaggi, come il C++, questa “limitazione” non esiste. Per arginare questo problema, in Java è stato introdotto il concetto di interfaccia. Attraverso l’utilizzo delle interfacce una classe può assumere diversi comportamenti: ciò che accade, in buona sostanza, con l’ereditarietà multipla. Ecco, quindi, che una classe, assumendo i comportamenti di più interfacce, può essere vista come una particolare istanza di quelle interfacce. L’esempio più classico è quello dell’ActionListener: è possibile scrivere una classe qualunque che implementi ActionListener e, conseguentemente, è possibile passare qualunque classe al metodo addActionListener(): sia essa un pannello, una Finestra o una qualunque altra cosa, purchè essa implementi l’interfaccia ActionListener, diventando così un oggetto di tipo ActionListener.
Un’ultima cosa prima di concludere: tutte le classi Java hanno come classe madre (chiamata anche superclasse) all’origine la classe Object. Questo significa che automaticamente quando scriviamo una classe essa deriva (senza doverlo specificare) da Object. Con questo espediente è possibile, quindi, parlare genericamente di un qualsiasi Object per riferirsi ad un oggetto di classe qualunque.
E con questo vado a concludere l’argomento. Resta bene inteso che, per problemi di spazio, non tutte le peculiarità sono state trattate, ma rimandiamo ad eventuali commenti l’approfondimenti di eventuali aspetti non trattati. Buona Programmazione.
Tags:classe ereditarietà extends interfaccia is a java object oggetto oop
10 Risposte
Traffyk
November 14th, 2007 at 14:43
1Davvero un ottimo articolo, non aggiungo nulla perchè si descrive da solo. Anche io in passato ho pubblicato alcune cosine su java, ho creato anche il classico giochino dello snake in due divertenti varianti
PS: segnalo nella mia rubrica
LeleFT
November 14th, 2007 at 14:50
2@Traffyk
Ti ringrazio per il commento e per i complimenti. Mi farebbe anche piacere vedere le versioni dello Snake.
Io per il passato ho realizzato diversi giochi, tra cui il Forza 4 (versione stand-alone e Applet), il Reversi (o Otello) anch’esso in duplice versione.
Oltre a vari altri programmi (per lavoro e per diletto, come una Chat, ad esempio).
BradipoMissile
November 14th, 2007 at 16:06
3@ Traffyk e LeleFT
Bravi ragazzi! Vedo che grazie alla mia idea del Bradipo Missile vi siete trovati a parlare di un argomento che conoscete bene (a differenza di me che sono completamente ignorante in materia!) e che vi interessa anche dal punto di vista professionale!
Sono molto contento per questo e invito Traffyk, se non lo ha già fatto, ad iscriversi ai miei Feed cliccando qui: http://feeds.feedburner.com/BradipoMissile
links for 2007-11-14 » Traffyk - I’m driving crazy, Blog
November 14th, 2007 at 16:23
4[…] Ereditarietà in Java | BradipoMissile.net […]
LeleFT
November 14th, 2007 at 16:44
5@Traffyk
Grazie per il link!!
Traffyk
November 14th, 2007 at 16:52
6Ciao Bradipo io ho sottoscritto il tuo feed gia da qualche giorno altrimenti non avrei mai potuto sapere del tuo articolo visto che raramente vado di blog in blog a leggere le notizie
ehehe
@LeleFT
Riguardo al mio giochino puoi trovare il codice sorgente dell’ultima versione e le due varianti di gioco (entrambi applet, non stand-alone) in questa pagina:
http://www.traffyk.com/tag/snake/ tutti gli articoli sono catalogati sotto il tag snake mentre quelli relativi a java in generale sotto il tag java. Io ho utilizzato questo linguaggio soltanto un po così per divertimento personale e per superare i due esami di java all’università.. poi l’ho accantonato un pochino ma quando posso ogni tanto qualche cosina la faccio
BradipoMissile
November 14th, 2007 at 16:58
7@ Traffyk
Che dire… grazie 1000 allora!!
In effetti avevo qualche sospetto che tu ti fossi già abbonato, dato che ti sei fiondato a colpo sicuro proprio su questo articolo… e non su altri!
7 giorni di links - The best of My/Del.icio.us #4 » Traffyk - I’m driving crazy, Blog
November 18th, 2007 at 16:49
8[…] Ereditarietà in Java […]
BradipoMissile
November 18th, 2007 at 17:20
9@ Traffyk
Grazie per la segnalazione nel tuo blog… io sarà meglio che impari a fare alltrettanto nei blog dei miei amici, e quindi anche nel tuo!!!
Chi mi aiuta a risolvere?
February 1st, 2008 at 23:02
10Qualcuno mi sà aiutare su questo esercizio in Java?
La classe Forma è una classe astratta che definisce schematicamente le caratteristiche comuni (di struttura e di comportamento) di alcune forme geometriche. La classe è posta alla sommità di una gerarchia di classi concrete che definiscono alcune figure geometriche.
La classe Forma implementa l’interfaccia Comparable e perciò fornisce un criterio per confrontare gli oggetti istanze delle classi da essa derivate.
Come esercitazione:
scrivere in Java l’implementazione delle classi derivate dalla classe Forma di seguito elencate:
public class Rettangolo extends Forma {/* . . . */ }
public class Cerchio extends Forma {/* . . . */ }
public class Quadrato extends Rettangolo {/* . . . */ }
scrive un classe con un metodo main di prova;
scrivere il corpo della classe derivata Disegno sapendo che tale classe realizza una collezione di forme geometriche e usa come struttura dati interna un array non ordinato;
riscrivere un classe con un metodo main di prova per verificare la classe Disegno
modificare la classe Disegno in modo che la collezione di forme geometriche risulti ordinata per valori crescenti di area;
opzionale, provare ad inserire nell’elenco oggetti di tipo Disegno.
RSS Iscriviti ai Feed dei commenti di questo articolo · TrackBack URI
Lascia un commento... please!!!
Autori
Categories
Calendario
Tag Cloud
Sondaggio
Blog Amici
Gente "Avanti"
Siti Interessanti
Benvenuto!
Pensieri / Aggiornamenti
Qualche statistica
Blog segnalato su
Recent Posts
Recent Comments
Meta