1. Le origini di Java e le sue caratteristiche
Andrea Pastore 19/03/2020 0
Java è un linguaggio di programmazione ad oggetti tra i più comuni al mondo, utilizzato praticamente in tutti i tipi di dispositivi, dai computer ai telefoni, distributori automatici e molto altro. Fu creato da Sun Microsystem nel 1995 ed è poi passato ad Oracle quando quest’ultima ha acquisito Sun.
La macchina virtuale Java
Una caratteristica di Java è quella di girare su tutti i sistemi operativi, senza che il codice venga ricompilato come avviene in altri linguaggi. Questa possibilità ci è data dalla Java Virtual Machine, che si occupa di leggere il codice Java tradurlo nel linguaggio macchina del dispositivo dove si trova.
Organizzazione del codice
Il codice Java è organizzato in classi, che sono contenute in package. Per ora ci basti sapere che una classe è un file contenente codice Java, può richiamare altre classi per fare compiti specifici. Le classi a loro volta sono suddivise in metodi, che possono essere richiamati dalla stessa classe o da altre classi.
Un programma java può avere un numero variabile di classi che può essere anche molto elevato (si pensi per esempio a programmi come Eclipse). Un programma Java deve avere sempre una classe che viene chiamata quando il programma va in esecuzione. Questa classe è chiamata classe main, capiremo più avanti questo concetto.
Un package è una cartella che contiene le classi Java. I progetti java possono essere molto vasti, quindi è necessario ordinare le classi in modo da essere consultabili. Ad esempio supponiamo di avere un programma di una biblioteca, un package potrebbe contenere tutte le classi Java deputate al salvataggio dei dati e un altro potrebbe contenere tutte le classi deputate alla gestione dell’interfaccia grafica.
Commenti
I commenti sono delle stringhe di testo che vegono utilizzate per spiegare il codice che si sta scrivendo. Quando scriviamo un programma non è detto che lo utilizzeremo solo noi, può darsi che quel codice vada in mano ad un collega. È bene quindi commentarlo per far capire a chi legge il codice (anche a noi stessi, se lo rileggiamo dopo un po’ di tempo!) cosa abbiamo fatto.I commenti in java si fanno in due modi:
// commento su singola riga
/*
* commento su più righe
* lo utilizziamo quando dobbiamo spiegare qualcosa di più elaborato
*/
Potrebbero interessarti anche...
Andrea Pastore 19/03/2020
6. Il costrutto switch
Ci sono casi in cui per prendere una decisione dobbiamo prendere in esame mole opzioni. Ad esempio supponiamo di dover gestire un livello di allarme: abbiamo una variabile coloreAllarme che può assumere i seguenti valori: rosso, arancione, giallo, verde. Se il colore è rosso stampiamo la frase “allerta critica”, se il colore è arancione stampiamo la frase “stato di allerta”, se il colore è giallo stampiamo “stato di pre allerta”, se è verde stampiamo “situazione tranquilla”. Il codice potrebbe essere questo:
if(coloreAllarme.equals("rosso")){
System.out.println("allerta critica");
}
else if(coloreAllarme.equals("arancione")) {
System.out.println("stato di allerta");
}
else if(coloreAllarme.equals("giallo")){
System.out.println("stato di pre-allerta");
}
else {
System.out.println("situazione tranquilla");
}
Quando però abbiamo tutte queste combinazioni possiamo usare il costrutto swithc, che consente di fare la stessa cosa, ma con meno righe di codice:
switch(coloreAllarme){
case "rosso":
System.out.println("Allerta critica");
break;
case "arancione":
System.out.println("stato di allerta");
break;
case "giallo":
System.out.println("stato di pre-allerta");
break;
case "verde":
System.out.println("situazione tranquilla");
break;
}
Il break serve per terminare le operazioni da eseguire con quella casistica. Se non viene inserito verranno eseguite anche le operazioni della casistiche successive fino a quando non si trova un break.
In caso di variabili numeriche non è necessario mettere le virgolette: ad esempio supponiamo di avere questo codice che a seconda del valore della variabile numeroPersone stampa se sono troppe, giuste, poche o troppo poche:
switch(numeroPersone){
case 2:
System.out.println("Troppo poche");
break;
case 3:
System.out.println("poche");
break;
case 4:
System.out.println("giuste");
break;
case 5:
System.out.println("troppe");
break;
default :
System.out.println("Nessuna opzione è stata selezionata");
}
la parola chiave default indica l’operazione da fare quando la variabile inserita nello switch non corrisponde a nessuno dei casi presenti.
Andrea Pastore 19/03/2020
12. Polimorfismo in Java
Alcuni linguaggi di programmazione consentono di decidere il comportamento dei metodi e costruttori in base al numero di variabili che vengono passate loro come parametro. Supponiamo ad esempio di avere una classe Java chiamata Utente, con tre variabili (id, nome, cognome) e due costruttori: il primo prenderà in input solo una variabile id, il secondo prenderà in input una variabile id, una variabile nome e una variabile cognome.
I due costruttori in java saranno i seguenti
public Utente(int id) {
this.id = id;
this.nome = “”;
this.cognome = “”;
this.email = “”;
}
public Utente(int id, String nome, String cognome) {
this.id = id;
this.nome = nome;
this.cognome = cognome;
}
Quando noi invochiamo il costruttore a seconda del numero di parametri che inseriamo Java userà il costruttore che combacia con i parametri inseriti ed eseguirà il codice contenuto all’interno. Java darà un errore solo se non trova un costruttore con il numeor di parametri da noi specificato. Ad esempio se scriviamo:
Utente utente = new Utente(3,”Mario”,”Rossi”,”mario@gmail.com”);
Otterremo un errore, perché non abbiamo definito un costruttore che prende in input quattro parametri. Tutto quello che abbiamo detto per i costruttori è valido anche per i metodi (del resto il costruttore non è altro che un metodo speciale). Prendiamo in esame il seguente metodo che stampa tutti i dati dell’utente:
public void stampaDati() {
System.out.println(this.id + “ ” + this.nome + “ ” + this.cognome + “ ” +this.email);
}
Come per i costruttori possiamo creare un altro metodo che ha lo stesso nome, ma prende in input un parametro per stabilire come devono essere stampati questi elementi. Stabiliamo due tipologie di stampa: essenziale che stampa solo nome e cognome, completa che stampa tutto. Se il parametro passato in input non corrisponde a nessuna di queste due cose allora questo metodo invoca a sua volta il metodo stampaDati senza parametri, che stamperà i dati senza formattazione.
public void stampaDati(String tipoVisualizzazione) {
if(tipoVisualizzazione.equals("essenziale")) {
System.out.println("Nome:"+this.nome+"; Cognome:"+this.cognome);
}
else if (tipoVisualizzazione.equals("completa")){
System.out.println("Id: "+this.id + "; Nome:"+this.nome+"; Cognome:"+this.cognome+"; Email:"+this.email);
}
else {
stampaDati();
}
}
Ereditarietà
L’ereditarietà è una caratteristica di molti linguaggi di programmazione moderni che consente di ottimizzare il codice scritto ed evitare ripetizioni. Ci sono casi in cui dobbiamo creare classi molto simili tra loro. Per questo molti linguaggi di programmazione consentono di usare il meccanismo dell’ereditarietà. Supponiamo di avere bisogno di questa due classi:
- Utente
id, nome, cognome, email,telefono - Fornitore
id, nome, cognome, email,telefono,partitaIva
notiamo che Fornitore è quasi uguale alla classe Utente, quindi non ha senso riscriverla. Quando creiamo la classe Fornitore che estenderà la classe Utente. Scriviamo le due classi per renderci conto del codice e delle differenze tra le due. Qui sotto vediamo la classe utente:
public class Utente {
private int id ;
private String nome;
private String cognome;
private String email;
private String telefono;
public Utente(int id, String nome, String cognome, String email, String telefono) {
this.id = id;
this.nome = nome;
this.cognome = cognome;
this.email = email;
this.telefono = telefono;
}
// Getter & setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
… tutti gli altri getter e setter
}
Vediamo ora la classe Fornitore. Come abbiamo capito Java ci consente di evitare di ricopiare la classe, basta dichiarare, al momento della creazione, che la nuova classe estende la classe Utente. Questo avviene con la parola chiave extends.
public class Fornitore extends Utente {
private String partitaIva;
public Fornitore(String partitaIva, int id, String nome, String cognome, String email, String telefono) {
super(id, nome, cognome, email, telefono, via, citta, cap);
this.partitaIva = partitaIva;
}
public String getPartitaIva() {
return partitaIva;
}
public void setPartitaIva(String partitaIva) {
this.partitaIva = partitaIva;
}
}
Notiamo alcune differenze con la classe Utente scritta sopra: innanzitutto vediamo che nel costruttore c’è la parola chiave super, seguita da una serie di parametri. Si tratta dei parametri del costruttore della classe Utente, che viene richiamato con il comando super. Ogni volta che noi estendiamo una classe il costruttore della nuova classe deve richiamare il costruttore della classe che estende. Fornitore estende la classe Utente, quindi il suo costruttore prende in input anche i parametri che richiede il costruttore di Utente, che invocherà con il metodo super().
Nota: quando una classe estende un’altra classe, la classe estesa è definita superclasse
Le interfacce in Java
Vediamo ora un altro concetto fondamentale della programmazione: le interfacce, che servono per standardizzare il codice.
Interfacce
Le interfacce vengono utilizzate per definire un tipo di dato e una classe, che però non viene implementato. Vengono definite solo le firme dei metodi che poi saranno implementate in altre classi. Vediamo un esempio di interfaccia:
public interface Libro {
public void stampaLibro();
public void setTitolo(String titolo);
public String getTitolo();
public void setNumeroPagine(int numeroPagine);
public int getNumeroPagine();
}
Per usare una determinata interfaccia dopo il nome della classe dobbiamo usare la parola chiave implements seguita dal nome dell'interfaccia. Appena facciamo questo il nostro ide ci segnalerà che i metodi dell'interfaccia non sono ancora implementati, clicchiamo su add unimplementated methods (potrebbe cambiare a seconda dell’ide usato) e il nostro ide li aggiungerà per noi, dobbiamo solo completarli con il codice all'interno.
In sostanza le interfacce consentono di standardizzare il codice: dueprogrammatori si accordano sui metodi e su come vengono chiamati, e poiai fini dell'interoperabilità delle classi non è importante come vieneimplementato. Nel tempo le implementazioni possono cambiare, ma rispettandole interfacce non ci saranno problemi di incompatibilità
Il paradigma MVC
La programmazione ad oggetti è utilizzata nel paradigma MVC (MODEL, VIEW, CONTROLLER), che consente una separazione delle logiche. Vediamo i tre elementi nel dettaglio:
- model
sono le classi cosi come le abbiamo viste. Quando creiamo una classe infatti definiamo degli oggetti ma non li usiamo in quell’istante - view
le viste rappresentano la parte del progetto che mostra i dati visivamente - controller
sono i file che consentono di rendere permanenti le operazioni sugli oggetti: creazione di nuovi elementi, modifica di elementi esistenti, eliminazione di elementi e anche recupero dei dati di un elemento. I controller nascondono le logiche sottostanti alle altre classi: potremmo voler salvare i dati in un file oppure nel database, per le classi esterne viene chiamato lo stesso metodo. Facendo passare tutte le operazioni di salvataggio, modifica, caricamento per il controller avremo solo una classe che gestisce queste operazioni, che si traduce in un vantaggio per la manutenibilità del codice, in quanto per apportare modifiche alla gestione degli oggetti dovremmo modificare solo la classe relativa.
Andrea Pastore 19/03/2020
7. Buone abitudini: indentare il codice
L’indentazione del codice consiste nell’inserire alcuni spazi all’inizio di una riga, ed è usata per aiutare a capire la struttura del codice scritto. Se ad esempio dobbiamo scrivere un if, per indicare il codice da eseguire se la condizione è verificata è buona norma indentare questo codice. Facciamo un esempio, prendiamo questo codice non indentato:
Tutti i caratteri sono scritti uno sotto l’altro e il codice risulta più difficile da leggere. Questo è un codice di poche righe, ma cosa succederebbe se fosse più corposo? Ci costringerebbe a perdere più tempo a capire cosa fa. Vediamo ora un codice ordinato:
Basta una rapida occhiata per capire il codice dove si trova e cosa fa.
Le regole dell’indentazione
Dobbiamo indentare il codice delle strutture di controllo (if, switch, for e altri), dei metodi e infine delle classi.