Luigi Arlotta
a- a+

Classi e Oggetti

In questo capitolo impareremo a definire le classi equindi ad utilizzare gli oggetti. Abbiamo giàdetto più volte nei capitoli precedenti che unoggetto è un insieme di dati efunzioni che ne definiscono lo stato ed ilcomportamento. In Java le classi sono dei modelli pergli oggetti, ovvero sono delle strutture dati utilizzate perdefinire le caratteristiche e le funzionalità di undeterminato tipo di oggetto. Una classe, una volta definita,viene instanziata creando un oggetto. E'importante non far confusione tra la definizione di unaclasse e l'instanzizione di un oggetto. Definire unaclasse consiste nell'elencare una serie diproprietà e funzioni, instanziare un oggetto invecevuol dire creare una variabile che presenta lecaratteristiche della classe da cui è stata generata.

Potremmo affermare che una classe è la definizione diun tipo di dato strutturato definito per rappresentareun'entità complessa quale può essere adesempio un conto bancario, un prodotto commerciale, unapersona. Affrontiamo dunque lo studio delle classi Javasupponendo di aver bisogno di progettare una classe cherappresenti un impiegato di una società.
Innanzitutto dobbiamo chiederci quali informazioni sono dinostro interesse, per la definizione della classe chechiameremo Impiegato. Trattandosi di un progetto afini didattici, semplificheremo il più possibile ladefinizione della classe Impiegato, partendo propriodalle proprietà di nostro interesse. Supponiamo che unimpiegato sia caratterizzato dalle informazioni relative alnome, cognome, anno di nascita, stipendio e posizione inazienda. Cominciamo a tradurre quanto detto fino ad orasecondo la sintassi Java.

public class Impiegato {private String nome;private String cognome;private int annoNascita;private int stipendio;private String posizione;final int stipendioMax;final int stipendioMin; }


Procediamo con la spiegazione di quanto scritto. La primariga contiene la dichiarazione della classe. In essa comparela parola chiave class che indica al compilatore Javal'operazione che stiamo eseguendo. La classeImpiegato è definita public, cioèpubblica. Questo vuol dire che potrà essere utilizzatao inclusa in altre classi o più in generale in altriprogetti, senza alcuna restrizione. Le parentesi graffe ({,}) racchiudono il codice che definisce la classe.All'interno compare la dichiarazione delleproprietà che abbiamo considerato di nostrointeresse per la definizione di un oggetto di tipo Impiegato.Tali proprietà sono il nome, cognome e posizione inazienda rappresentate da tre variabili di tipo Stringchiamate rispettivamente nome, cognome eposizione. A queste si aggiungono le informazioniriguardanti anno di nascita e stipendio, rappresentate daaltre due variabili di tipo int chiamaterispettivamente annoNascita e stipendio. Infinecompare la dichiarazione di due costanti di tipo intero cherappresentano rispettivamente lo stipendio minimo e massimoche può ricevere un impiegato: stipendioMin estipendioMax. Osservate che nessuna di questevariabile è stata inizializzata in questa fase didefinizione della classe.
Ogni dichiarazione di variabile contenuta nella classeè composta [...].
[Pending: dichiarazioni variabili e parola chiave private]

Una volta definite le proprietà di una classedobbiamo aggiungere una serie di funzioni, che in javavengono più propriamente detti metodi cheoperando sulle proprietà descrivendo il comportamentoe le operazioni che sarà possibile effettuare suglioggetti che verranno generati dalla classe. I metodi chesiamo interessati a definire per la classe Impiegatosono riportati in tab.8.1 dove è descritta anche lafunzione alla quale dovranno assolvere.



motraNome() visualizzerà nome e cognome dell'impiegato
calcolaStipendio() restituirà un valore intero pari allo stipendio
calcolaEta(int anno) restituirà un valore intero paril'età dell'impiegato in particolare anno
variaStipendio(int variazione) varia lo stipendio
aumentaStipendio(int aumento) incrementerà lo stipendio di una quantitàpari a aumento
riduciStipendio(int riduzione) ridurrà lo stipendio di una quantità paria riduzione
Tab.8.1: Metodi della classe Impiegato



Una volta completata la definizione della classeImpiegato sarà possibile instanziare diversioggetti di tipo Impiegato, ognuno caratterizzato da unproprio stato. Col termine stato indichiamol'insieme dei valori assegnati alle proprietà diogni oggetto. Ad esempio instanzieremo un oggetto cherappresenti l'impiegato Mario Rossi, nato nel 1964,... un secondo oggetto che rappresenta l'impiegatoLuigi Verdi, nato nel 1970, ... e così via. Adognuno di questi oggetti, identificato da un nome esattamentecome avviene per le variabili, sarà possibileapplicare i metodi appena elencati, ed a secondadell'oggetto a cui verranno applicati questi metodiotterremo risultati diversi, appunto, in base allo statodell'oggetto in questione. Dovendo definire questa classea fini didattici abbiamo inserito tre metodi che modificanola proprietà stipendio, mentre probabilmente nesarebbe bastato uno. Questa scelta è stata fatta perevidenziare alcune proprietà dei metodi che verrannoevidenziate nel corso di questo capitolo.

Cominciamo a scrivere il codice per la definizione deimetodi. Per definire il metodo mostraNome()scriveremo:


public void mostraNome(){System.out.println(nome + " " + cognome); }


Il metodo è costituito da un'intestazione e da uncorpo racchiuso tra le parentesi graffe. Soffermiamoci adosservare l'intestazione:

public void mostraNome()

in essa compare la visibilità del metodopubblic che definisce il metodo come pubblico,cioè accessibile (visibile) dall'esterno dellaclasse. In poche parole questo vuol dire che una voltainstanziato l'oggetto, il metodo potrà essereliberamente richiamato per operare sull'oggetto stesso.Ai metodi pubblici si contrappongono quelli definitiutilizzando la parola chiave private, i quali nonpossono essere richiamati dall'esterno, ma possono essereutilizzati solo all'interno della classe. Parleremo deimetodi privati tra poco. La seconda parola chiave,void, indica il tipo di dato restituito dal metodo altermine dell'esecuzione. Generalmente un metodo esegueun'elaborazione su dati immessi dall'esterno e/osulle proprietà dell'oggetto su cui vienerichiamato. L'elaborazione porta ad un risultato cheviene restituito come output. Questo valore può esseredi tipo intero (int), decimale (float odouble), stringa (String), o di un qualsiasialtro tipo. In fase di progettazione di un metodo ènecessario dichiarare il tipo di valore che verràrestituito al termine dell'esecuzione delle istruzionicontenute nel metodo. Se il metodo non restituisce nessunvalore si usa la parola chiave void. Questo èil nostro caso, infatti il metodo mostraNome()visualizza nome e cognome dell'oggetto Impiegatosu cui è stato richiamato senza restituire alcunvalore. Infine, nella riga d'interstazione, compare ilnome del metodo, seguito da una coppia di parentesi tonde incui possono essere opzionalmente indicati i parametririchiesti in input dal metodo. Nel caso dimostraNome() nessun parametro di input èrichiesto.
Il corpo della funzione è costituito semplicementedall'istruzione:

System.out.println(nome + " " + cognome);

Istruzione già incontrata in precedenza, il cui scopoè visualizzare una stringa contenente il valore delleproprietà nome e cognomedell'oggetto di tipo Impiegato su cui èstato richiamato il metodo separate da uno spazio.

Passiamo a definire il secondo metodo della classe Impiegato,calcolaStipendio().

public int calcolaStipendio (){return stipendio; }

 

Anche in questo caso vogliamo analizzare l'intestazionedel metodo. Rispetto al metodo precedente in questo casoabbiamo dichiarato che il metodo restituisceun'informazione (output) sotto forma di numero intero.Questa dichiarazione viene rispettata nel corpo del metodoutilizzando la parola chiave return. returninfatti, seguito da una variabile o da una costante, assolveproprio a questo compito. In questo caso dunque vienerestituito, come output, il valore contenuto nellaproprietà stipendio. E' importanteassicurarsi che il tipo della variabile restituita coincidacon il tipo del metodo dichiarato nell'intestazione. Inquesto caso il tutto risulta corretto in quanto abbiamodichiarato che il metodo restituisce un valore di tipo intero(int), che è effettivamente anche il tipo dellavariabile stipendio.

Procediamo nella definizione del metodo calcolaEta().

public int calcolaEta (int annoCorrente){int eta = annoCorrente - annoNascita;if ((eta>=16) && (eta<=90))return eta; elsereturn 0;}

Nell'intestazione di questo metodo compareun'ulteriore differenza rispetto ai due metodi appenadescritti. In questo caso abbiamo un metodo pubblico, cherestituisce un valore di tipo intero e che richiede unparametro di input, anch'esso di tipo intero. Questoè quanto si deduce osservando l'intestazione delmetodo. In particolare il tipo del parametro di inputrichiesto è indicato tra le parentesi che seguono ilnome del metodo. Oltre al tipo viene indicato il nome cheverrà attribuito al valore intero passato in input perfarvi riferimento all'interno del corpo della funzione.Nel corpo della funzione viene dichiarata ed inizializzatauna nuova variabile di tipo intero, chiamata eta.L'inizializzazione di questa variabile dipende dallaproprietà annoNascita dell'oggetto su cuiviene richiamato il metodo e dal parametroannoCorrente passato come input. Per come èformulata l'istruzione di inizializzazione dellavariabile eta è ovvio che essa contienel'età dell'impiegato. Segue un'istruzioneif... then... else... il cui scopo ècontrollare che il parametro di input sia valido. Ilcontrollo cosiste nel verificare che la variabile eta,a seguito dell'inizializzazione abbia assunto un valorecompreso tra 16 e 90. L'età di 16 anni è laminima età lavorativa imposta per legge, per quantoriguarda il limite superiore si è invece supposto dinon aver impiegati ultranovantenni. Se il controllo ha esitopositivo viene restituito un numero intero rappresentatel'età dell'impiegato in questione, altrimentiviene segnalato l'errore tramite la restituzione diun'età pari a 0.

Definiamo il metodo variaStipendio().

private void variaStipendio (int variazione){if (stipendio + variazione > stipendioMin)stipendio = stipendio + variazione; elsestipendio = stipendioMin;if (stipendio > stipendioMax)stipendio = stipendioMax;}

 

Dall'intestazione del metodo risulta chevariaStipendio() è un metodo privato (definitotale dalla parola chiave private). Questacaratteristica fa si che una volta instanziato un oggetto ditipo Impiegato, non sarà possibile richiamaredirettamente su di esso il metodo variaStipendio(). Unmetodo privato può essere richiamato solo da altrimetodi definiti internamente alla classe di appartenenza. Nelnostro caso il variaStipendio() verràutilizzato dai metodi aumentaStipendio() eriduciStipendio(), per modificare la proprietàstipendio. Il metodo riceve in input un parametrointero, a cui viene attribuito il nome variazione, chepuò essere sia positivo che negativo. Nel corpo delmetodo viene effettuato un primo controllo tramiteun'istruzione if... then... else... sul parametrovariazione al fine di verificare che una eventualeeccessiva riduzione dello stipendio non lo faccia risultareinferiore al valore stipendioMin che indica lostipendio minimo percepito da un impiegato. Un secondocontrollo invece assicura che lo stipendio, una voltaregistrata la variazione non superi la soglia massimadefinita tramite la costante stipendioMax.

Analizziamo i metodi aumentaStipendio() eriduciStipendio(). Osserviamo come questi facciano usodel metodo privato variaStipendio() per assolvere alproprio compito, quindi senza doversi preoccupare di eseguirealcun tipo di controllo sulle eventuali eccessive variazionidella proprietà stipendio.

public void aumentaStipendio (int incremento){variaStipendio (incremento); }


Il metodo aumentaStipendio() è un metodopubblico, non restituisce alcun valore ma ne richiede uno ininput di tipo intero (int) cui viene dato il nomeincremento. Il metodo opera sulla proprietàstipendio dell'oggetto richiamandovariaStipendio().

Definiamo il metodo riduciStipendio().

 

public void riduciStipendio (int riduzione){variaStipendio (riduzione*(-1)); }

 

Il metodo riduciStipendio() è un metodopubblico, non restituisce alcun valore ma ne richiede uno ininput di tipo intero (int) cui viene dato il nomeriduzione. Il metodo opera sulla proprietàstipendio dell'oggetto su cui viene richiamatoutilizzando il metodo variaStipendio().

Fino ad ora abbiamo definito proprietà e metodi dellaclasse Impiegato. Siamo a buon punto, ma non abbiamoancora concluso il nostro lavoro, infatti, se ben ricordate,al momento della dichiarazione delle proprietà, cisiamo limitati ad elencarle, senza preoccuparci di comequeste verranno inizializzate. L'inizializzazione di unoggetto, al momento della sua creazione, avviene attraversoun metodo particolare detto costruttore. Ilcostruttore è un metodo che viene richiamatoautomaticamente ogni volta che viene creato un nuovo oggettoal fine di inizializzarlo. Il costruttore per essere distintodagli altri metodi deve avere lo stesso nome della classe,quindi nel nostro caso, si deve chiamare Impiegato().Definiamo il costruttore della classe Impiegato.

public Impiegato (String nome, String cognome, int annoNascita, String posizione){stipendioMin = 750;stipendioMax = 2000;this.nome = nome;this.cognome = cognome;this.annoNascita = annoNascita;stipendio = stipendioMin;this.posizione = posizione; }

Analizzando l'intestazione del costruttore della classeImpiegato notiamo subito che si tratta di un metodopubblico (public), che non è specificato alcuntipo di dato restituito. Tutti i costruttori devono averequeste due caratteristiche. Non è possibile definirecostruttori di tipo private o che restituiscano unqualche tipo di valore in output. Il costruttore della classeImpiegato richiede in input quattro parametri: nome,cognome, anno di nascita e posizione del nuovo oggetto ditipo Impiegato che verrà generato. Osserviamoche ai parametri passati in input viene dato lo stesso nomedelle proprietà della classe. Questa procedura, chealtrimenti potrebbe generare confusione, viene risoltautilizzando la parola chiave this all'interno delcorpo del costruttore. L'uso di this è unmodo per far riferimento ad una proprietàdell'oggetto che stiamo generando. In questo modo, puravendo entrambe lo stesso nome, non si farà confusionetra le variabili passate al costruttore e le corrispondentiproprietà dell'oggetto. Per evitare l'usodella parola chiave this avremmo potuto scrivere:

public void Impiegato (String n, String c, int a, String p){stipendioMin = 750;stipendioMax = 2000;nome = n;cognome = c;annoNascita = a;stipendio = stipendioMin;posizione = p; }


All'inizio questo potrebbe sembrarvi il modo piùsemplice di procedere, tuttavia una volta appreso ilfunzionamento della parola chiave this, viverrà più naturale scrivere i costruttori, edin generale ogni altro metodo, come descritto nel primoesempio.

All'interno del corpo del costruttore possiamo richiederel'esecuzione di qualsiasi tipo di operazione, tuttaviaè buona norma limitarsi all'inizializzazione delleproprietà dell'oggetto.

A questo punto abbiamo decisamente completato la definizionedella classe Impiegato! Per comodità vi riportodi seguito l'intero codice. Ho ordinato il codice secondole convenzioni in uso tra i programmatori Java, ossia primail costruttore, poi i metodi pubblici e privati, quindi leproprietà pubbliche, quelle private ed infine lecostanti.


public class Impiegato {public Impiegato (String nome, String cognome, int annoNascita, String posizione){stipendioMin = 750;stipendioMax = 2000;this.nome = nome;this.cognome = cognome;this.annoNascita = annoNascita;stipendio = stipendioMin;this.posizione = posizione; }public void mostraNome(){System.out.println(nome + " " + cognome); }public int calcolaStipendio (){return stipendio; }public int calcolaEta (int annoCorrente){int eta = annoCorrente - annoNascita;if ((eta>=16) && (eta<=90))return eta; elsereturn 0; }public void aumentaStipendio (int incremento){variaStipendio (incremento); }public void riduciStipendio (int riduzione){variaStipendio (riduzione*(-1)); }private void variaStipendio (int variazione){if (stipendio + variazione > stipendioMin)stipendio = stipendio + variazione; elsestipendio = stipendioMin;if (stipendio > stipendioMax)stipendio = stipendioMax;}private String nome;private String cognome;private int annoNascita;private int stipendio;private String posizione;final int stipendioMax;final int stipendioMin; }

 



Ti potrebbe interessare anche

commenta la notizia

Ci sono 3 commenti