Java facile facile

Quanto segue è una presentazione delle istruzioni principali di Java, fatte da un principiante e diretto a principianti. Saranno graditissimi commenti e contributi dei lettori del documento.

Antonia Jeanrenaud            niettajean@libero.it

Argomenti:

Esempio

//Esempio di classe che definisce un generico cane

public class Cane {

private int peso;

//metodo per richiedere il peso del cane

public int getPeso( ) {

return peso;

}

//metodo per dare il peso del cane

public void setPeso(int pesodelcane) {

peso = pesodelcane;

}

}

(salviamo quanto sopra in un file chiamato Cane.java)

//Esempio di applicazione che chiama la classe Cane

public class TestPeso {

public static void main (String [ ] args) {

//creo l'oggetto cane

Cane pluto = new Cane();

pluto.setPeso(35); //vedremo dopo come cosi’ "chiamo il metodo setPeso e passo il

//valore 35"

System.out.println(" il peso di Pluto e' " + pluto.getPeso());

}

}

(salviamo quanto sopra in un file chiamato TestPeso.java)

Istruzioni per eseguire l’esempio

javac Cane.java (javac richiama il compilatore ovvero il programma javac.exe)

javac Testpeso.java

java TestPeso (java richiama il loader/interprete ovvero il programma java.exe)

il peso di Pluto e' 35

CONSIDERAZIONI su quanto detto

La dichiarazione di una classe NON crea alcun oggetto, semplicemente descrive un oggetto.

NON alloca memoria. È come uno stampino che useremo per creare N oggetti: chiamiamo instanziazione la " creazione dell’oggetto con la classe".

L’oggetto viene creato e alloca memoria con l’istruzione:

Nomeclasse oggetto = new Nomeclasse();

nell’esempio di prima:

//creo l'oggetto cane

Cane pluto = new Cane();

creeremo un oggetto di classe Cane chiamato pluto.

Potremo fare:

//creo altri oggetti cane

Cane lilli = new Cane();

Cane bassotto = new Cane();

Cane pippo = new Cane();

ESAME dei due metodi utilizzati:

//metodo per richiedere il peso del cane

public int getPeso( ) {

return peso;

}

//metodo per dare il peso del cane

public void setPeso(int pesodelcane) {

peso = pesodelcane;

}

Il metodo getPeso restituisce il valore del peso: valore conosciuto in quanto interno alla classe Cane. Il valore viene fornito al "return, ovvero ritorno" dalla chiama da al metodo. Il metodo getPeso è definito:

-public in quanto richiamabile da altre classi

-int in quanto restituisce un valore intero (peso).

Il metodo setPeso imposta il peso con il valore passato come argomento (pesodelcane).

"void" sta a indicare che il metodo non ritorna valori (cioe’ non esiste alcuna istruzione del tipo "return qualchecosa").

Il metodo setPeso ha in parentesi (int pesodelcane) gli argomenti passati al metodo; nell’esempio il pesodelcane viene impostato col valore dell’argomento passato

Accesso agli oggetti

Abbiamo visto come con una classe instanziamo ( creiamo) più oggetti, ad esempio più cani. Vediamo come possiamo utilizzare, accedere ai dati degli oggetti.

Dato che ogni oggetto ha gli stessi attributi (ogni cane ha il suo peso) per richiamare l’attributo di un oggetto (il peso di pluto) dovrò utilizzare il seguente formato di istruzione:

<oggetto>.membro ovvero pluto.peso

pluto.peso=35; //assegno all’oggetto pluto, attributo peso, il valore 35

Allo stesso modo, utilizzando un metodo, possiamo assegnare il valore risultante dal metodo:

pluto.setPeso(35);

utilizzo il metodo setPeso per assegnare 35 al peso di pluto.

Perché nel nostro esempio abbiamo eseguito "pluto.setPeso(35)" invece di pluto.peso=35; ???

Perche’ nel nostro oggetto Cane, l’attributo peso era "private", quindi la classe TestPeso non lo conosceva. Se avessimo chiamato public peso, avremmo potuto assegnare direttamente 35 (provate i due esempi di programma: verrà un errore di compilazione).

 

Ereditarietà tra le classi

Abbiamo detto che l’ereditarietà consiste nella capacità di classi "figli", cioe’ gerarchicamente al di sotto della classe padre, di ereditare atttributi e metodi dalla classe padre. Vediamo un esempio.

Abbiamo la classe Impiegati, in cui definiamo un attributo di nome ruolo, di tipo string, cui assegniamo per valore la stringa Impiegato. Abbiamo la classe Dirigenti, figlio della classe Impiegati, che avrà gli stessi metodi ed attributi della classe Impiegati (cioè la classe Dirigenti è una sottoclasse di Impiegati). Per indicare il legame gerarchico, l’istruzione è :

nomeclassefiglio extends nomeclassepadre

Esempio

class ClassImpiegati {

String ruolo="Impiegato";

}

class ClassDirigenti extends ClassImpiegati {

}

public class TestEredita {

public static void main (String [ ] args) {

ClassDirigenti b=new ClassDirigenti();

ClassImpiegati a=new ClassImpiegati();

System.out.println(a.ruolo); // Stampa "Impiegato"

System.out.println(b.ruolo); // Stampa "Impiegato"

}

}

Nell’esempio, vediamo che l’attributo ruolo viene definito nella classe ClassImpiegati e ereditato nella classe ClassDirigenti. Infatti anche per i dirigenti, esiste l’attributo ruolo, con il valore assegnato nella classe ClassImpiegati.

Per provare l’esempio,

1)scrivere il testo in un file chiamato TestEredita.java

2) eseguire javac TestEredita,java (attenzione ai caratteri maiuscoli)

3) eseguire java testEredita

Casting fra le classi

Torniamo all’esempio di classi, dove la classe padre era "impiegato" e la classe figlio era "dirigente". Abbiamo detto che la classe "figlio" eredita dalla classe padre attributi e metodi. Ma in pratica una classe figlio può avere differenti attributi e metodi rispetto a quelli definiti per il padre, ne può avere in più (caso di ampliamneto:widening), in meno (caso di riduzione:narrowing), o di ridefinizione di attributi o metodi in maniera differente.

Questa operazione di modifficare attributi e proprietà del padre si chiama "casting".

La sintassi del casting è (nome_classe)nome_oggetto

Esempio

class ClassImpiegati

{

String ruolo="Impiegato";

}

class ClassDirigenti extends ClassImpiegati

{

String ruolo="Dirigente";

}

public class TestCasting {

public static void main (String [ ] args) {

ClassDirigenti b=new ClassDirigenti();

ClassImpiegati a;

a=(ClassImpiegati)b; // Casting

System.out.println(a.ruolo); // Stampa "Impiegato"

System.out.println(b.ruolo); // Stampa "Dirigente"

}

}

per provare l’esempio:

1) creare un file chiamato TestCasting.java con un editor di testo, e salvarlo in formato testo

2) eseguire il comando javac TestCasting.java (attenzione ai caratteri maiuscoli)

3)eseguire il comando comando javac TestCasting java (attenzione ai caratteri maiuscoli)

Esaminiamo le istruzioni dell’esempio

class ClassImpiegati

definisce una classe che si chiama ClassImpiegati

String ruolo="Impiegato";

la classe ha un attributo di tipo String (stringa di caratteri);

l’attributo si chiama ruolo e ha come valore la stringa "Impiegato"

class ClassDirigenti extends ClassImpiegati

String ruolo="Dirigente"

definisce una classe che si chiama ClassDirigenti e che "estende" la classe ClassImpiegati,

di cui e’ figlio, ereditando l’attributo ruolo, ma modificandone il valore, in una stringa

"Dirigente"

public class TestCasting {

public static void main (String [ ] args) {

definiamo la classe principale.della nostra applicazione di esempio, che chiamiamo

TestCasting (il metodo main è INDISPENSABILE e deve essere "public static void",

per ora non specifichiamo perche’…)

ClassDirigenti b=new ClassDirigenti();

instanziamo un oggetto b di tipo ClassDirigenti, avra’ attributi definiti nella classe

ClassDirigenti

ClassImpiegati a;

instanziamo un oggetto a di tipo ClassImpiegati

a=(ClassImpiegati)b; // Casting

System.out.println(a.ruolo); // Stampa "Impiegato"

System.out.println(b.ruolo); // Stampa "Dirigente

sintassi del casting è (nome_classe)nome_oggetto, instanziamo un oggetto a di classe

ClassImpiegati,

 

Da notare la differenza rispetto all’esempio presentato in precedenza: il valore dell’attributo "ruolo" è stato modificato dal casting della classe. (vedi esempio riportato nel paragrafo dell’Ereditarietà tra le classi).

 

I Metodi

I metodi sono le funzioni di una classe. Ogni metodo ha il compito di "eseguire qualcosa", quindi può restituire il risultato di determinate operazioni. Il risultato potrà essere una stringa , un numero, un dato booleano: il "tipo di ritorno" del metodo dipenderà dal tipo di risultato atteso.

Dichiarazione dei metodi

<modificatore> <tipo di ritorno> <nome del metodo> (lista degli argomenti) {

istruzioni del metodo

----------------------------------

}

Se un metodo non restituisce alcun risultato, va dichiarato come void, come ad esempio il metodo main, che abbiamo usato sino ad ora:

public static void main (String [ ] args)

Ogni metodo ha una lista degli argomenti consistente in coppie di tipi e nomi di argomenti (o parametri), separate da virgole. Se il metodo non utilizza parametri, la lista dovrebbe essere vuota.

Abbiamo visto l’esempio col metodo getPeso:

//metodo per richiedere il peso del cane

public int getPeso( ) {

il tipo di ritorno è int dato che il metodo restituisce il valore intero Peso del cane.

 

 

I flussi di controllo

In un metodo inseriremo le istruzioni necessarie per ottenere il risultato previsto.

Abbiamo visto le istruzioni di assegnazione di valori ad argomenti, e le istruzioni di "Instanziazione" di classi. Abbiamo visto sino ad ora istruzione che vengono eseguite.. in sequenza, cioè una dopo l’altra, man mano che vengono incontrate.

Ci sono istruzioni che "modificano " il percorso del programma, in funzione di determinate condizioni. Una condizione può essere ad esempio legata al valore assunto da una variabile. In questa categoria si trovano le istruzioni di flusso di controllo.

L’istruzione:

if (condizione) {

istruzione;

}

else {

istruzione;

}

sta a indicare il differente percorso del programma, in funzione della condizione.

La condizione (vera) (falsa) deriva da una operazione ad esempio di confronto di valori, o in ogni caso una operazione che produce un "valore booleano vero o falso ". Per la valutazione della "condizione" si utilizzano gli "operatori booleani".

Operatori Boolean

Gli operatori boolean sono:

• & (valutazione completa),

• && (corto circuito and: es. A && B, B non è valutato se A è false);

or:

• | (valutazione completa),

• ||(corto circuito or: A ||B , B non è valutato se A è true);

not:

• !(es. !A==0)

Per altro, i booleani possono essere interrogati per uguaglianza (==) e diversità (!= ).

Esempio

uguaglianza

if (A==10)

System.out.println(‘A e’ uguale a 10’);

else

System.out.println(‘A non e’ uguale a 10’);

diversità

if (A!=10)

System.out.println(‘A non e’ uguale a 10’);

else

System.out.println(‘A e’ uguale a 10’);

Istruzione di salto condizionato (switch)

Se il programma deve effettuare operazioni differenti non in funzione di una variabile "vera" o "falsa", ma in funzione del valore di un attributo (esempio nome del mese: Gennaio, Febbraio..) l’istruzione if vista in precedenza non e’ adeguata. In questo caso si può utilizzare l’istruzione "switch", che "splitta" il flusso del programma in piu’ rami.

Formato dell’istruzione

switch (espressione) {

case costante1:

Istruzione;

Istruzione;

………………

break;

case costante2:

Istruzione;

Istruzione;

Istruzione;

………………

break;

default:

Istruzione;

Istruzione;

………………

break;

}

L’istruzione switch valuta un’espressione intera il cui valore viene utilizzato per determinare un’etichetta case opportuna tra quelle elencate nel blocco che la segue.

Espressione può essere di tipo char, byte, short o int

Un’etichetta case o default non interrompe l’esecuzione dello switch, cioè non implica la fine dell’esecuzione delle istruzioni.

Per questo motivo viene inserito il comando break che porta l’esecuzione al di fuori del blocco dello switch.

Il codice dell’etichetta default viene eseguito se non si verifica nessuno dei casi previsti.

 

Esempio

class ClassSwitch {

public void prova (int i) {

switch (i) {

case 1:

System.out.println("lunedi'");

break;

case 2:

System.out.println("martedi'");

break;

case 3:

System.out.println("mercoledi'");

break;

case 4:

System.out.println("giovedi'");

break;

case 5:

System.out.println("venerdi'");

break;

case 6:

System.out.println("sabato'");

break;

case 7:

System.out.println("domenica");

break;

default:

System.out.println("valore errato");

break;

}

}

}

public class TestSwitch {

public static void main (String [ ] args) {

//chiama il metodo che scrive il nome del giorno della setttimana corrispondente al valore passato

ClassSwitch b=new ClassSwitch();

b.prova(5); //con questo valore scrivera’ venerdi’

}

}

Per provare l’esempio,

1) creare il file di testo e salvarlo col nome TestSwitch.java

2) eseguire javac TestSwitch.java

2) eseguire java TestSwitch

Provare a modificare l’istruzione b.prova(5) inserendo nelle parentesi qualsiasi valore al posto di 5.