In questo articolo impareremo quali sono i passi da seguire quando si vuole impostare una semplice classe in java. Nello specifico creeremo una classe in grado di gestire un orologio.
NB: È data per scontata la conoscenza anche marginale del concetto di classe, di metodo, di variabile, di casting, di costruttore, di overload, di oggetto e delle parole chiave public, private e static in quanto questi argomenti verranno spiegati soltanto superficialmente.
Innanzitutto analizziamo bene il nostro problema e cerchiamo di comprenderlo a fondo.
Problema: costruire una classe che permetta di gestire un orario in Ore, Minuti e Secondi.
Ci è subito chiaro che la nostra classe dovrà avere tre variabili globali: una per gestire le ore, una per i minuti e un’ altra per i secondi. Cominciamo quindi a scrivere la parte iniziale della nostra classe:
class Orologio{
private byte ore;
private byte minuti;
private byte secondi;
}
Abbiamo dichiarato le nostre variabili di tipo byte. Questo perchè a rigor di logica il valore di ognuna di queste variabili non supererà mai 59 in quanto sia i minuti che i secondi andranno da 0 a 59 mentre le ore da 0 a 23. Quindi il tipo byte è perfetto poichè permette di memorizzare un range di valori che vanno da -128 a +127 occupando solo un byte di memoria.
Altra cosa da notare è che abbiamo reso le nostre variabili private, ovvero accessibili soltanto dall’interno della classe. Questo per conformarci alle regole della buona programmazione e rendere la nostra classe pià robusta. In seguito vedremo come rendere accessibili queste variabili anche dall’ esterno creando dei metodi appositi.
Dopo aver impostato le nostre variabili è necessario definire almeno un costruttore per poterle inizializzare. Un costruttore è una funzione particolare che viene chiamata nel momento in cui viene creato un’ istanza della classe ed ha proprio lo scopo di “inizializzare l’oggetto”, ovvero di impostare adeguatamente i valori delle variabili di istanza (nel nostro caso le varibili ore, minuti e secondi). Implementiamo quindi il nostro costruttore aggiungendo alla classe il seguente codice:
public Orologio(byte ore, byte minuti, byte secondi){
this.ore = (byte) (Math.abs((int)ore)%24);
this.minuti = (byte) (Math.abs((int)minuti)%60);
this.secondi = (byte) (Math.abs((int)secondi)%60);
}
Cerchiamo di spiegare come è stato implementato questo costruttore:
Innanzitutto abbiamo pensato che nel momento della creazione di un oggetto Orologio si voglia specificare un orario iniziale, di conseguenza dobbiamo gestire necessariamente tre parametri: uno per le ore, uno per i minuti e uno per i secondi.
Per capire meglio il concetto vediamo un piccolo esempio di creazione di un oggetto orologio a partire dal nostro costruttore.
Immaginate di avere un file java che possa accedere alla classe Orologio da noi creata e che abbia il seguente codice:
class nuovaclasse{
public static void main(String[] args){
Orologio a = new Orologio( (byte) 10, (byte) 30, (byte) 0);
Orologio b = new Orologio( (byte) 22, (byte) 50, (byte) 35);
Orologio c = new Orologio( (byte) 0, (byte) 0, (byte) 0)
}
}
Il codice sovrastante crea tre oggetti appartenenti alla nostra classe Orologio chiamati a,b e c rispettivamente con i seguenti orari: (si noti che è stato effettuato un casting a byte in quanto abbiamo definito i parametri del nostro costruttore come byte)
- a - 10:30 (le dieci e mezza)
- b - 22:50:35 (le 22 e 50 e 35 secondi)
- c - 00:00:00 (mezzanotte)
Adesso che probabilmente è pià¬π chiaro il significato del costruttore vediamo cosa fa nello specifico il nostro costruttore rivedendo il codice scritto in precedenza:
this.ore = (byte) (Math.abs((int)ore)%24);
this.minuti = (byte) (Math.abs((int)minuti)%60);
this.secondi = (byte) (Math.abs((int)secondi)%60);
Il costruttore và a modificare le variabili di istanza inserendo i valori passati come parametri di inizializzazione. questi parametri pero’ vanno ripuliti tramite una semplice funzione matematica e riconvertiti in byte. Ciò è fatto per evitare che erroneamente vengano passati valori negativi o valori che eccedono il massimo raggiungibile per le ore o per i minuti e i secondi.Questa funzione prende i parametri passati in valore assoluto e nel calcola il modulo per il valore massimo possibile. Ad esempio se nel parametro relativo alle ore scriviamo 25 o -25 il costruttore provvederà automaticamente a impostare l’ora ad 1.
Adesso possiamo implementare altri costruttori extra nella nostra classe che vengono richiamati se vengono passati parametri differenti, ecco un elenco di alcuni possibili costruttori che potrebbero essere aggiunti alla nostra classe:
//prende come parametri ore e minuti
public Orologio(byte ore,byte minuti){
this(ore,minuti,(byte)0);
}
// prende come parametri ore e minuti come interi
// (evita di dover fare la conversione a byte in fase di creazione dell'oggetto)
public Orologio(int ore,int minuti){
this((byte)ore,(byte)minuti,(byte)0);
}
// prende come parametri un numero di secondi superiore a 60 e calcola l'orario corrispondente
public Orologio(long secondi){
this.ore = (byte)((secondi/3600)%24);
this.minuti = (byte)((secondi/60)%60);
this.secondi = (byte)(secondi%60);
}
// prende come parametri 3 interi
// (evita di dover fare la conversione a byte in fase di creazione dell'oggetto)
public Orologio(int ore, int minuti, int secondi){
this((byte)ore,(byte)minuti,(byte)secondi);
}
// nessun parametro. Crea un orologio impostato a mezzanotte - 00:00:00
public Orologio(){
this((byte)0,(byte)0,(byte)0);
}
Una volta impostati i nostri costruttori possiamo iniziare a definire i pià¬π svariati metodi che potrebbero ritornarci utili quando vorremo utilizzare un oggetto Orologio. Prepariamoci un elenco delle “features” che implementeremo nella nostra classe cosନ da aver un idea precisa di ciò che andremo a sviluppare:
- Una serie di metodi per leggere e modificare le variabili di istanza
- Una serie di metodi per fare conversioni da orari a numero di secondi passati da mezzanotte e viceversa
- Una serie di metodi per fare calcoli con gli orari (somme e differenze)
- Una serie di metodi per stampare l’orario in vari formati
Cominciamo inserendo i metodi per gestire le variabili di istanza. Queste variabili erano state rese private e quindi i metodi che creeremo li imposteremo pubblici. Ciò ci permette di creare dei metodi che verificano ed eventualmente corregono i valori che devono essere inseriti prima di inserirli. Questo meccanismo conferisce sicuramente maggiore solidità alla nostra classe in quanto le nostre variabili non conterranno mai dei valori anomali.
Per ogni variabili essenzialmente abbiamo bisogno di due operazioni: una di lettura e una di modifica (di scrittura) quindi dovremmo creare due gruppi di metodi appositi. Essi per convenzione vengono chiamati metodi “set & get” (imposta e recupera). Vediamo come metterli a punto:
// METODI GET
public byte getOre(){
//restituisce le ore
return this.ore;
}
public byte getMinuti(){
//restituisce i minuti
return this.minuti;
}
public byte getSecondi(){
//restituisce i secondi
return this.secondi;
}
// METODI SET
public void setOre(byte ore){
//reimposta le ore
this.ore = (byte)(Math.abs((int)ore)%24);
}
public void setOre(int ore){
this.setOre((byte)ore);
}
public void setMinuti(byte minuti){
//reimposta i minuti
this.minuti = (byte)(Math.abs((int)minuti)%60);
}
public void setMinuti(int minuti){
this.setMinuti((byte)minuti);
}
public void setSecondi(byte secondi){
//reimposta i secondi
this.secondi = (byte)(Math.abs((int)secondi)%60);
}
public void setSecondi(int secondi){
this.setSecondi((byte)secondi);
}
Ecco invece il codice restante per implementare tutti gli altri metodi restanti. Il funzionamento del codice è spiegato nelle righe di commento.
public static Orologio secOrario(long secondi){
//conversione da secondi passati dall' ora 00:00:00 a Orologio
//restituisce un oggetto Orologio con l'orario convertito
Orologio O = new Orologio(secondi);
return O;
}
public long orarioSec(){
//converte l'Orologio corrente in secondi passati dall' ora 00:00:00
return (long)this.secondi + (long)this.minuti*60 + (long)this.ore * 3600;
}
public Orologio somma(Orologio orario){
//somma un Orologio All'Orologio corrente e restituisce un nuovo Orologio
Orologio o = new Orologio();
o.setSecondi( (byte)((this.secondi + orario.secondi)%60) );
o.setMinuti( (byte)( (this.minuti + orario.minuti + (this.secondi + orario.secondi)/60 ) % 60)) ;
o.setOre((byte)((this.ore + orario.ore + (this.minuti + orario.minuti)/60) % 24));
return o;
}
public Orologio somma(long secondi){
//somma i secondi specificati
//e restituisce un nuovo Orologio
Orologio o = new Orologio(secondi);
return this.somma(o);
}
public Orologio sottrai(Orologio orario){
//sottrae un Orologio all'orologio corrente e restituisce un nuovo Orologio
Orologio o = new Orologio(Math.max( 0, this.orarioSec() - orario.orarioSec() ));
return o;
}
public Orologio sottrai(long secondi){
//sottrae i secondi specificati
//e restituisce un nuovo Orologio
Orologio o = new Orologio(secondi);
return this.sottrai(o);
}
public static Orologio somma(Orologio orario1,Orologio orario2){
//restituisce la somma tra due orologi
return orario1.somma(orario2);
}
public static Orologio differenza(Orologio orario1,Orologio orario2){
//restituisce la differenza tra due orologi
return orario1.sottrai(orario2);
}
public String format(String formatString){
//formatta l'orario utilizzando una stringa di formattazione
/*
H - ore da 0 a 23
h - ore da 0 a 12
O - ore da 00 a 23
o - ore da 00 a 12
p - AM o PM
m - minuti da 0 a 59
M - minuti da 00 a 59
s - secondi da 0 a 59
S - secondi da 00 a 59
*/
String uksub = new String();
if (this.ore <= 12) {
uksub = "AM";
}else{
uksub = "PM";
}
String[] parsevalue = {Byte.toString(this.ore),Byte.toString(this.minuti),Byte.toString(this.secondi),Integer.toString(this.ore%12)};
for (int i=0;i < parsevalue.length; i++){
if(parsevalue[i].length() == 1) parsevalue[i] = "0"+parsevalue[i];
}
formatString = formatString.replace("H",Byte.toString(this.ore));
formatString = formatString.replace("h",Integer.toString(this.ore % 12));
formatString = formatString.replace("O",parsevalue[0]);
formatString = formatString.replace("o",parsevalue[3]);
formatString = formatString.replace("m",Byte.toString(this.minuti));
formatString = formatString.replace("M",parsevalue[1]);
formatString = formatString.replace("s",Byte.toString(this.secondi));
formatString = formatString.replace("S",parsevalue[2]);
formatString = formatString.replace("p",uksub);
return formatString;
}
public void stampa(){
//stampa l'Orologio nel formato hh:mm:ss
System.out.println(this.toString());
}
public void stampa(String formatString){
//stampa utilizzando l'orario
System.out.println(this.format(formatString));
}
public void stampaUK(){
//stampa hh(12):mm:ss AM/PM
System.out.println(this.format("o:M:S p"));
}
public String toString(){
return(this.format("O:M:S"));
}
}
Con questo la nostra classe Orologio è pronta per essere utilizzata. Potete scaricare questo
file zip
dove troverete il codice sorgente della classe Orologio e un’ ulteriore classe che mostra degli esempi su come utilizzare la classe Orologio.
Spero di essere stato abbastanza chiaro, eventualmente richiedete maggiori spiegazioni lasciando un commento o contattandomi via mail a loige{chiocciola}hotmail{punto}com, sarà felice di aiutarvi
Alla prossima!





