User interface design
Davide Pirrò
March 2023
Sintassi Java
Introduzione a Java
Java è un linguaggio di programmazione orientato agli oggetti. È sia interpretato che compilato. Un file sorgente .java infatti deve essere compilato in bytecode in un file .class, e successivamente interpretato dalla Java Virtual Machine. Ogni file sorgente .java deve contenere una sola classe, e il nome della classe deve essere uguale al nome del file (esclusa l’estensione).
Convenzioni di denominazione
In Java esiste una convenzione per i nomi di classi, variabili e metodi:
- I nomi delle classi iniziano per lettera maiuscola.
- I nomi di ogni parola oltre la prima iniziano sempre per lettera maiuscola.
- I nomi di variabili e metodi iniziano per lettera minuscola.
Basi di Java
In Java abbiamo alcuni tipi base:
- byte
- short
- int
- long
- float
- double
- boolean
- char
Non esistono tipi unsigned. Esistono gli array built-in. I costrutti di base sono identici al C++, tranne per il fatto che esiste un tipo di switch che al posto di break usa yield seguito da un valore e che può essere assegnato ad una variabile.
Classi
In Java tutto il codice va inserito in dei metodi di una classe. Il metodo principale che viene eseguito è il metodo main (con i specificatori public, static e void). Esiste per le classi lo specificatore di visibilità (public, protected). Se non viene indicato alcuno specificatore di visibilità, le classi avranno visibilità di package.
Ogni classe può avere dei costruttori, ha la keyword this che indica l’oggetto stesso della classe e ci sono i campi statici, così come i membri statici, in maniera simile al C++. Quando assegniamo ad una variabile un oggetto in Java in realtà stiamo copiando il riferimento in memoria di quell’oggetto. Un riferimento ha formato: NomeOggetto@indirizzo.
I riferimenti in Java sono simili al funzionamento dei puntatori in C++, con la differenza che i riferimenti non vanno dereferenziati per essere normalmente utilizzati. Quando passiamo un parametro ad un metodo, il parametro viene passato per copia di valore nel caso dei tipi base e per copia di riferimento nel caso degli oggetti.
Grazie alla presenza del garbage collector, in Java non dobbiamo preoccuparci di deallocare manualmente la memoria. Per creare librerie di classi logicamente collegate tra di loro si utilizzano i Package. Per utilizzare le classi all’interno di un package dobbiamo utilizzare la direttiva import. Esistono anche i moduli, ovvero insieme di package che sono responsabili anche delle proprie risorse, ovvero di tutti i file che essi utilizzano. Per utilizzare i moduli, le risorse e i package che fanno parte del modulo vanno specificate all’interno di un file particolare.
Per prendere dati da linea di comando dobbiamo utilizzare l’oggetto Scanner di java.utils.
Stringhe
In Java le stringhe sono rappresentate da un oggetto speciale. Sono immutabili ed è possibile utilizzare charAt per prendere un carattere. Se si vogliono creare stringhe mutabili esistono i tipi StringBuffer e StringBuilder (quest’ultimo è più efficiente ma non garantisce che il codice sia thread safe). Esistono inoltre le stringhe formattate.
Record
In Java esiste un tipo di classe particolare quando si vogliono creare classi immutabili, che hanno tutti i dati disponibili nel costruttore e che hanno solo metodi getters: i record. Nei record possiamo implementare anche altri metodi, oltre a poter definire costruttori diversi.
Ereditarietà
Attraverso la keyword extends è possibile ereditare una superclasse in una sottoclasse. Con questo metodo possiamo ereditare al più una classe per volta. Inoltre qualsiasi classe noi scriviamo eredita implicitamente la classe Object, che ha i seguenti metodi:
- boolean equals(Object o);
- String toString();
- int hashCode();
- Object clone();
Possiamo effettuare l’override dei metodi nelle classi figlie. Inoltre, poiché tutte le classi ereditano Object, possiamo costruire array misti. Infatti, possiamo sempre eseguire la conversione da una sottoclasse a una superclasse (upcast). Non è vero però il contrario: per effettuare il downcast dobbiamo specificarlo e inoltre è sempre meglio controllare che i due oggetti siano compatibili tramite la keyword instanceof (checked downcast). Possiamo chiamare metodi della superclasse tramite la keyword super. Inoltre, con la stessa keyword (ma con le parentesi tonde) possiamo chiamare il costruttore della superclasse nella sottoclasse.
Si può usare la keyword final per definire:
- Attributi costanti (come const di C++)
- Metodi su cui non posso effettuare l’override
- Classi che non posso ereditare
Posso avere classi astratte attraverso l’utilizzo della keyword abstract, che deve essere utilizzata sia per la classe che per i metodi astratti (senza un’implementazione del metodo).
Interfacce
Un’interfaccia è un tipo speciale di costrutto simile ad una classe, che contiene però solo attributi statici e metodi (che possono non essere implementati o avere un’implementazione di default). Indicano, a differenza degli oggetti, una proprietà comune a più tipi di oggetti. Le classi che implementano un’interfaccia devono implementare almeno tutti i metodi non di default e si dice che rispettano il contratto. Una classe può implementare anche più di un’interfaccia.
Per poter comparare due oggetti si deve implementare l’interfaccia Comparable, che ha un solo metodo: compare. Se non si vuole implementare quest’interfaccia, ma si vuole comunque comparare due oggetti (per esempio nel sort), si può implementare l’interfaccia Comparator “on-demand”. Esistono inoltre alcuni Comparator già pronti.
-
User Interface - Personal Report
-
Riassunto esame Interface design, Prof. Caruso Giovanni, libro consigliato La caffettiera del masochista, Donald A.…
-
Riassunto esame Ergonomia cognitiva, Prof. Guercio Elena, libro consigliato User Experience design , Debora Botta
-
Appunti di Keyword Design