Corso JAVA
Lezione n° 05
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
I Caratteri
Prima di riprendere con le classi e gli oggetti, faremo una breve digressione
su un argomento che abbiamo solo accennato nelle lezioni precedenti,
ovvero l’utilizzo dei caratteri e delle stringhe.
Quando una variabile è dichiarata come char, per assegnargli un valore
(ovvero una lettera) si utilizza il seguente tipo di assegnamento:
char lettera; // Si dichiara che alla variabile lettera è associato un
carattere.
lettera = ‘a’; // Per assegnare una lettera alla variabile occorre
racchiuderla tra gli apici.
Un array di caratteri si inizializza nel modo seguente:
char lettere[] = {‘a’,‘b’,‘c’,‘d’,‘e’};
2
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Le Stringhe
A differenze degli int, float, char, bool, ecc.. le stringhe non sono un tipo
fondamentale, String infatti è una classe pertanto le stringhe non sono variabili
ma sono oggetti, anche se sono oggetti un po’ particolari.
String Nome;
// Si dichiara che la variabile Nome contiene un
oggetto di tipo stringa.
Nome = “Carlo”;
//Per assegnare una stringa ad una variabile, la si
racchiude tra i doppi apici (per i caratteri gli apici
sono singoli).
Un array di stringhe di inizializza nel modo seguente;
Nomi String [] = {“Carlo”, “Michele”, “Erica”, “Marta”};
Le stringhe, a differenza degli altri oggetti, dispongono di uno speciale operatore +
che permette la concatenazione.
3
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
I Metodi
Abbiamo visto la scorsa lezione che un metodo di una classe si dichiara così:
<Modificatore> <Tipo> NomeMetodo( <Tipo> Nome_Parametro, … )
{
Istruzioni;
}
Nell’esempio del ContoCorrente il metodo Prelievo_Consentito infatti era dichiarato
nel seguente modo:
public boolean Prelievo_Consentito(float importo_prelievo){ istruzioni };
Questo metodo quindi prende in input un valore float (prelievo) e mi restituisce un
booleano.
Come fa il metodo a restituirmi un valore booleano? Semplice!! Tra le varie istruzioni
presenti tra le parentesi graffe ci sarà un istruzione return (valore da restituire).
Nell’esempio infatti per ogni ramo dell’istruzione if era presente un return; se l’importo
era sufficiente return(true); se non lo era return(false);
4
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Istanziare un Oggetto
Sappiamo adesso come si definiscono delle semplici classi, ma ancora non abbiamo visto come
si utilizzano. Mettiamo il caso di aver definito una classe Studente:
public class Studente {
private String Nome;
private String Cognome;
private int Matricola;
public int Media;
Manca qualcosa!!!
Il Costruttore!!!
public Studente (String nome, String cognome, int matricola) {
Nome=nome;
Cognome=cognome;
Matricola=matricola;
}
public void Stampa_Nome( ) { System.out.println("Il nome dello studente è: " + Nome); }
public void Stampa_Cognome( ) { System.out.println("Il cognome dello studente è: " + Cognome); }
public void Aggiungi_Voto_per_Media(int Voto) { }
}
5
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Istanziare un Oggetto (2)
Se nel nostro programma vogliamo creare un oggetto studente utilizzeremo la
seguente sintassi:
nome_classe nome_oggetto = new nome_classe (parametri, dipende dal costruttore);
Quindi se vogliamo creare un istanza della classe Studente dovremo scrivere:
Studente Stefano = new Studente (“Stefano”, “Bianchi”, 208300);
In questo modo ho creato un oggetto Studente chiamato Stefano.
Come vedete i parametri che sono inseriti tra parentesi sono lo stesso numero e dello
stesso tipo di quelli presenti nella dichiarazione:
Studente (String nome, String cognome, int matricola);
A questo punto nella mia applicazione potrò effettuare la chiamata di uno dei metodi
che l’oggetto offre, es.
Stefano.Stampa_Cognome(); //eseguirà la stampa del cognome dell’oggetto Stefano
6
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
I tre principi della programmazione
ad oggetti.
Tutti i linguaggi di programmazione orientati agli oggetti offrono i seguenti
meccanismi che implementano il modello orientato agli oggetti:
INCAPSULAMENTO: E’ il meccanismo che controlla l’accesso ad una struttura
dati solo attraverso opportune operazioni. Abbiamo visto questa caratteristica
nella scorsa lezione, quando abbiamo parlato dei modificatori d’accesso. Il
metodo private ad esempio impedisce di vedere metodi e strutture dati
dall’esterno di una classe.
Le altre due caratteristiche che vedremo in questa lezione sono:
EREDITARIETA’: E’ il meccanismo attraverso il quale un oggetto acquisisce le
proprietà di un altro. Fondamentale perché sostiene il concetto di della
classificazione gerarchica.
POLIMORFISMO: E’ il meccanismo attraverso il quale si è possibile progettare
un’interfaccia generica per specificare una classe generale di azioni (una sola
interfaccia, più implementazioni);
7
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà
Il meccanismo dell’ereditarietà, dal punto di vista semantico (e fortunatamente, come
vedremo anche dal punto di vista realizzativo) è piuttosto semplice.
Nella vita reale quando si sente parlare di ereditarietà, ci si riferisce molto spesso alla
sua concezione medico-genetica, ovvero si intende la trasmissibilità per via
genetica di determinate caratteristiche degli individui.
Es. Il colore dei capelli o degli occhi di solito è uguale a quello di uno dei due
genitori, perché è un carattere ereditario.
E’ possibile estendere questo concetto anche in ambito informatico: l’ereditarietà
consente di definire una classe detta sottoclasse (o classe derivata) a partire da
una classe preesistente detta superclasse o classe base. La sottoclasse "eredita"
implicitamente tutte le caratteristiche (attributi e metodi) della classe base.
Concettualmente, l'ereditarietà indica una relazione di generalizzazione: essa
corrisponde infatti all'idea che la superclasse rappresenti un concetto generale e
la sottoclasse rappresenti una variante specifica di tale concetto generale.
8
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà (2)
L’ereditarietà permette quindi di concentrarsi sulle definizioni delle classi che conosciamo,
mantenendo la possibilità di definire in seguito nuove versioni, le quali potranno ereditare
le proprietà e le caratteristiche delle classi originali, aggiungendone delle nuove.
Così facendo sarà possibile costruire una gerarchia di classi in cui le modifiche e le estensioni
siano concentrate nei punti in cui sono realmente necessarie.
Ad esempio: (l’avevamo già accennato alla lavagna nella scorsa lezione…) supponiamo di aver
definito una classe Persona… se vogliamo fare una classe Studente, perché replicare i
campi Nome, Cognome, ecc.. E i metodi Stampa_Nome.. se c’è una classe che ce li ha già!
Persona
Studente
String Nome
String Cognome
int Età
int Esami
Meglio concentrarsi
sullo sviluppo di
nuove funzionalità
void Chi_Sei( );
9
Istituto Statale di Istruzione Superiore “F. Enriques”
int Matricola
String Facoltà
void Chi_Sei( );
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà (3)
Consideriamo l’ipotesi che nel nostro passato avessimo implementato la classe Persona come
illustrato qui di seguito…
class Persona {
protected int eta;
protected String nome;
protected String sesso;
public Persona(String nome, String sesso, int eta) {
this.nome=new String(nome);
this.sesso=new String(sesso);
this.eta=eta;
}
public void ChiSei() {System.out.println("Nome: "+nome+", sesso: "+sesso+", eta: "+eta); }
}
10
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà (4)
11
…poi è possibile creare la classe Studente che eredita da Persona tramite il comando extends, senza
preoccuparsi di nuovo su attributi come il nome l’età ecc. ma concentrandosi su quello che servono…
class Studente extends Persona
{
protected int esami;
protected int matricola;
protected String facolta;
public Studente(String nome, String sesso, int eta, int esami,int matricola, String facolta) {
super(nome, sesso,eta);
this.esami=esami;
this.matricola=matricola;
this.facolta=new String(facolta);
}
public void ChiSei() {
super.ChiSei();
System.out.println(“Facolta di "+facolta+", matricola: "+matricola+", esami sostenuti: "+esami);
}
}
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà (5)



Java implementa soltanto l’ereditarietà singola, in quanto ciascuna classe di Java
ha una sola superclasse.
Al vertice della gerarchia di tutte le classi Java c’è la classe Object
Un nuovo oggetto ha accesso a tutti i metodi della sua classe e delle sue
progenitrici.
MECCANISMO DEL LATE BINDING
Quando si richiama un metodo su un oggetto,
l’interprete ne cerca dapprima la definizione nella
classe dell’oggetto stesso;
se non la trova, cerca nella superclasse e risale la
gerarchia fino a trovarla.
Nel caso esistano più metodi con lo stesso
nome,tipo restituito e stessi parametri, viene
eseguito il metodo trovato per primo.
12
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Ereditarietà (6)
13
Nell’esempio precedente, oltre ad extends, sono state utilizzate delle keywords che fino ad ora
non avevamo visto: this, super.
THIS:
Ogni oggetto può accedere a tutti i suoi membri (variabili e metodi) usandone semplicemente il
nome; il nome completo di un membro è però this.membro dove this è un identificatore
che è associato all’oggetto corrente.
Nel corpo di un metodo o di un costruttore, la variabile predefinita this quindi denota l'oggetto
che sta eseguendo il metodo (o costruttore).
Normalmente quando non esiste ambiguità sui nomi dei membri, l’uso dell’identificatore è
superfluo. Lo si usa quando un campo o un parametro locale ha lo stesso nome di uno
definito nella classe.
SUPER:
L'identificatore super ha un uso simile a this ma, a differenza di quest'ultimo, invece di fare
riferimento all’oggetto corrente fa riferimento alla superclasse.
Attraverso super è possibile invocare la versione originale di un metodo di cui è stato fatto
l’overridind, che altrimenti risulterebbe inaccessibile a causa del meccanismo del late
binding visto prima (eseguirebbe il primo che trova avente num. e tipo parametri corretti).
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(1)
Il polimorfismo è considerato, dopo l’incapsulamento e l’ereditarietà, il “terzo pilastro” della
programmazione ad oggetti; per spiegarlo però dobbiamo partire dall’ereditarietà….
Proviamo a scrivere una semplice gerarchia di classi:
public class Animale {
public void interroga( ) { System.out.println(“Grunt”); }
}
public class Ghepardo extends Animale {
public void interroga( ) { System.out.println(“Groar!”); }
}
public class Muflone extends Animale {
public void interroga( ) { System.out.println(“MOOOO!”); }
public void salta( ) { System.out.println(“hop!”); }
}
public class Armadillo extends Animale {
14
Istituto Statale di Istruzione Superiore “F. Enriques”
}
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo (2)
La classe Animale definisce un metodo interroga( ) che stampa una stringa sullo
schermo.
Grazie all’ereditarietà, sono assolutamente sicuro che tutte le classi che ereditano da
Animale avranno questo metodo, in particolare si ha che la classe Armadillo non
aggiunge niente alla sua superclasse, mentre le altre due sottoclassi (Ghepardo e
Muflone) ridefiniscono il metodo interroga( ) per fornire la loro particolare
implementazione. La classe Muflone aggiunge anche un nuovo metodo che non è
contenuto nella classe base.
Il senso di tutto questo è: se un metodo (o un campo) non privato è definito nella
classe base, allora è sicuramente definito anche in tutte le classi derivate. Una
classe derivata può fornire la propria particolare implementazione del metodo,
cioè fare quello che si chiama un “overriding” (ridefinizione) del metodo, ma non
può eliminarlo; se non presente abbiamo visto che sarà il meccanismo del late
binding a cercare nelle classi progenitrici il metodo appropriato.
Queste sono tutte caratteristiche fondamentali dell’ereditarietà.
15
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(3)
Possiamo dire che le classi derivate sono in relazione “è un” con la classe base. Esempio, ciascun
oggetto di tipo Armadillo “è un” oggetto di tipo Animale. A sua volta la classe Animale
eredita implicitamente dalla classe Object, quindi un Armadillo è anche un Object. Ciascun
oggetto, quindi, può essere visto come se appartenesse a più classi: la sua classe vera e propria
e tutte le classi da cui eredita. Quando scriviamo:
Armadillo arm = new Armadillo(); //Per istanziare un oggetto Armadillo.
abbiamo un oggetto di nome arm che è allo stesso tempo un Armadillo, un Animale e un
Object.
Questo è un concetto intuitivo: tutti gli armadilli sono animali, che a sua volta sono “oggetti”.
Il fatto che un oggetto abbia
più di un tipo ha alcune
conseguenze interessanti,
guardate questo semplice
programma:
public class Upcast {
public static void main(String[] args) {
Animale bestia;
bestia = new Armadillo();
}
16
Istituto Statale di Istruzione Superiore “F. Enriques”
}
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(4)
Il codice della diapositiva precedente è semplicissimo, eppure può lasciare perplessi.
Nella prima riga del main si dichiara una variabile bestia contenente un oggetto Animale.
Nella seconda riga creiamo un oggetto di tipo Armadillo e lo assegniamo a tale variabile.
Quindi abbiamo definito una variabile di un tipo e gli abbiamo assegnato un oggetto di un altro
tipo, eppure il programma può essere compilato e lanciato senza errori.
Per quale motivo il compilatore non restituisce un errore?
Il compilatore non “protesta” perché non ne trova il motivo: il nostro assegnamento è
valido. Possiamo sempre assegnare un Armadillo ad una variabile contenente oggetti di
tipo Animale, perché un Armadillo è a tutti gli effetti un animale. Avremmo potuto anche
assegnare lo stesso oggetto ad una variabile contenente un tipo Object:
Object o = new Armadillo( );
Attenzione: un Armadillo è un animale, ma non vale il contrario:
Armadillo a = new Animale( ); // errore!
17
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(5)
Il motivo per cui non restituisce un errore nel primo caso, ma lo restituisce nel
secondo, stà nel fatto che una sottoclasse ha sicuramente (come minimo) tutta
l’interfaccia della classe base, ma non è detto che la classe base abbia tutta
l’interfaccia sottoclasse (e’ il principio dell’ereditarietà visto fino ad ora).
In generale, Java non ci permette di assegnare liberamente un oggetto ad una
variabile di tipo diverso, esempio: Armadillo a = new Muflone(); // errore!
L’unico caso, quindi, in cui possiamo assegnare un oggetto ad una variabile di tipo
diverso è quando il tipo dell’oggetto è un sottotipo del tipo di tale variabile.
In questo caso il compilatore fa un’operazione che si chiama “cast verso l’alto” o, in
inglese, “upcasting”: usa una variabile di tipo “superiore” per contenere un
oggetto di tipo “inferiore”.
La stessa cosa succede se anziché usare un assegnamento facciamo la conversione in
modo meno esplicito, esempio: se un metodo richiede come parametro un tipo
animale, è possibile passargli un oggetto armadillo, visto che è anch’esso un
animale.
18
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(6)
Tutto questo può sembrare inutile.
Perché non dovremmo essere precisi, e chiamare armadilli gli armadilli e mufloni i mufloni?
La risposta richiede un esempio pratico:
public class Upcast2 {
public static void main(String[] args) {
Armadillo arm = new Armadillo();
RiproduciVerso(arm);
Muflone muf = new Muflone();
RiproduciVerso(muf);
Ghepardo ghep = new Ghepardo();
RiproduciVerso(ghep);
}
private static void RiproduciVerso(Animale anim) { anim.interroga( ); }
}
19
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(7)
In UpCast2 abbiamo un metodo RiproduciVerso(), che essendo statico si comporta
come una normale funzione; Il metodo accetta come parametro un animale, ma
anziché passare alla funzione oggetti di classe Animale, le passiamo oggetti di
sottoclassi di Animale, che vengono convertiti con un cast verso l’alto.
La novità sta nel fatto che la funzione RiproduciVerso() non si limita a ricevere gli
oggetti, ma chiama il loro metodo interroga() per scrivere sullo schermo il verso
dell’animale in questione.
Cosa appare sullo schermo? Il metodo RiproduciVerso() non ha idea dell’esistenza
delle classi Armadillo, Muflone e Ghepardo, aa solo che riceverà un Animale, e
“vede” sempre l’oggetto che gli viene passato come se fosse un animale.
Dato che stiamo invocando il metodo interroga() di un animale, potremmo pensare
che sullo schermo sarà sempre stampato il verso del generico animale:
Grunt
Grunt
Grunt
20
In realtà, il risultato è questo:
Istituto Statale di Istruzione Superiore “F. Enriques”
Grunt
MOOOO!
Groar!
Corso di Programmazione in Java – Lezione n° 05
Polimorfismo(8)
Ciascun animale ha prodotto il suo verso (con l’eccezione dell’armadillo, che non ridefinisce il
metodo interroga( ) e usa quindi l’implementazione fornita nella classe Animale).
Si è ottenuto un risultato tale che sembra che la funzione RiproduciVerso( ) “sapesse” che
l’oggetto che le veniva passato non era un generico animale, ma di volta in volta un
armadillo, un muflone, un ghepardo.
In realtà quello che succede è ancora più sottile: la funzione RiproduciVerso() si disinteressa
completamente delle sottoclassi, tutto quello che le interessa è ricevere un animale.
Quindi, poiché l’oggetto è un animale, la funzione RiproduciVerso( ) è sicura che l’oggetto che
ha ricevuto avrà un metodo interroga( ), pertanto “manda un messaggio” a questo oggetto,
chiedendogli di eseguire interroga( ).
L’oggetto sa di essere, ad esempio, un muflone, quindi usa l’implementazione del metodo
interroga() specifica della classe Muflone, ecc..
Riassumendo la funzione conosce una “caratteristica generale” dell’oggetto (il fatto che esiste
un metodo interroga()) e lascia all’oggetto la responsabilità di comportarsi secondo le sue
caratteristiche particolari (la particolare implementazione del metodo).
Questa caratteristica del linguaggio, grazie alla quale possiamo usare un oggetto senza sapere
esattamente di che tipo sia e come si comporterà, si chiama Polimorfismo.
21
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Overriding e Overloaded
Abbiamo detto che quando una sottoclasse ridefinisce un metodo ereditato, si dice che fa un
“overriding”.
Grazie all’overriding, una classe derivata può avere un’implementazione diversa dalla propria
classe base, pur condividendone l’interfaccia; nel nostro esempio, le classi Ghepardo e
Muflone fanno entrambe un overriding del metodo interroga() della classe Animale.
Attenzione a non confondere l’overriding con l’overloading, che è un’operazione molto
diversa.
L’overloading è il “sovraccarico” di significati di un metodo; In pratica, significa che abbiamo
più metodi con lo stesso nome, che si distinguono solo per il numero e il tipo dei parametri
in ingresso. Ecco un esempio:
public class Vongola extends Animale {
public void interroga() { System.out.println(“Glup!”); }
public void interroga(int num) {
for (int i = 1; i <= num; i++) System.out.println(“Glup!”); }
22
}
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Overriding e Overloaded(2)
23
La classe Vongola contiene un metodo “overloaded” infatti esistono due versioni del metodo
interroga(), e il compilatore sceglie di volta in volta la versione giusta in base ai parametri
della chiamata.
Due metodi con lo stesso nome convivono tranquillamente se hanno parametri in ingresso
diversi.
Quando si usa l’overloading dobbiamo sempre ricordare particolari: Il primo è che il tipo del
parametro in uscita non è sufficiente a distinguere i metodi; Il secondo è che due metodi
che si distinguono solo per i parametri di ingresso sono, a tutti gli effetti, due metodi
diversi, anche se hanno lo stesso nome.
Ecco un esempio sbagliato relativo al primo particolare:
public class Bah {
public void unMetodo( ) { System.out.println(“Glup!”); }
public int unMetodo( ) { System.out.println(“Glup!”); return (1); }
}
Questa classe dà un errore di compilazione, perché una classe non può contenere due metodi
con lo stesso nome e gli stessi parametri in ingresso, anche se i due metodi restituiscono
tipi diversi.
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Overriding e Overloaded(3)
La classe Vongola contiene due versioni del metodo interroga() (e questo è
un overloading), e una delle due sostituisce l’implementazione della
classe base Animale (questo è un overriding).
Quindi è possibile usare overriding e overloading contemporaneamente, a
patto di non fare confusione: la versione di interroga() che non prende
parametri in ingresso è quella che si ritrova nell’interfaccia di Animale,
mentre la versione che accetta un intero è un metodo diverso e
completamente nuovo aggiunto dalla classe Vongola.
24
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Final
25
Esistono metodi che per loro natura non dovranno mai essere modificati, in particolare non
dovrà essere permesso di fare overriding su questi metodi.
Possiamo usare la parola chiave final per indicare che un metodo non può essere ridefinito
nelle classi derivate; ad esempio:
public class Pesce extends Animale {
public final void interroga( ) { System.out.println(“...”); }
}
Anche la classe Pesce eredita dalla classe Animale, e come tutti gli oggetti di classe Animale
può essere interrogato, pertanto si ridefinisce il metodo interroga().
Ma i pesci sono muti, e il metodo stampa solo tre puntini di sospensione.
Possiamo anche scrivere altre classi che derivano da Pesce, esempio, un Branzino, ma tutte le
sottoclassi di Pesce avranno una limitazione: il metodo interroga() di Pesce è stato
dichiarato final, quindi non può essere ridefinito in una sottoclasse.
Dal punto di vista del design, la cosa ha perfettamente senso: quando abbiamo scritto la classe
Pesce abbiamo deciso che tutti i pesci sono muti, e non vogliamo che qualche sottoclasse
trasgredisca a questa regola. Se la classe Branzino provasse a fornire una propria
implementazione del metodo interroga(), il risultato sarebbe un errore di compilazione.
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Final(2)
Se ci sono motivi di design particolari, possiamo anche dichiarare final un’intera
classe:
public final class Uomo extends Animale {
public void interroga( ) {
System.out.println(“So’ er mejo dell’evoluzione!”); }
public void inquina() { // … }
}
Ora, nessuna classe può ereditare da Uomo, provateci e otterrete un errore di
compilazione.
Naturalmente, tutti i metodi di una classe final sono implicitamente final.
Avevano già visto la parola chiave final in una delle prime lezioni, vi ricordate?
Quando abbiamo parlato delle costanti…l’utilizzo di final è lo stesso, si vuole
impedire che qualcuno modifichi il valore contenuto in una variabile dopo la sua
inizializzazione con un certo valore.
26
Istituto Statale di Istruzione Superiore “F. Enriques”
Corso di Programmazione in Java – Lezione n° 05
Vantaggi dell’Ereditarietà e del
Polimorfismo.
L’Ereditarietà ed il Polimorfismo hanno diversi vantaggi, ma occorre conoscerli bene
per apprezzarli a fondo. In caso contrario si rischia di applicarli in modo inutile,
o forse anche dannoso.
Sappiate comunque che i programmi che usano bene il polimorfismo e l’ereditarietà
sono più facili da espandere e modificare, infatti di solito i problemi più grandi
non si incontrano quando si scrive un programma, ma quando lo si modifica, di
solito per aggiungere funzionalità nuove.
Questa operazione non è quasi mai indolore, e spesso costringe a riscrivere intere
parti del programma, nei casi peggiori, il programma diventa così disordinato e
complesso che conviene buttarlo via e ricominciare da zero.
Nessuna tecnica può, da sola, risolvere questo problema, ma il polimorfismo e
l’ereditarietà sono due degli strumenti che possono rendere l’aggiornamento dei
programmi molto più facile.
27
Istituto Statale di Istruzione Superiore “F. Enriques”
Scarica

Lezione n° 05