vuoi
o PayPal
tutte le volte che vuoi
Introduzione alle interfacce e alle classi generiche
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.
Le classi generiche sono simili ai template di c++. Sfruttano il fatto che Object è comune a
Tutti i tipi, tranne quelli di base. Per ovviare a questo problema esistono delle classi wrapper che servono per rendere degli oggetti i tipi di base. Ce n'è una per tipo e sono:
- Byte
- Short
- Boolean
- Character
- Integer
- Long
- Float
- Double
Sono in tutto e per tutto sostituibili con i tipi built in, solo che possono far parte dei generics. Sono immutabili.
1.8 Strutture dati
In java esistono una serie di interfacce e di classi che implementano delle strutture dati:
- List, interfaccia implementata da:
- ArrayList
- Vector
- LinkedList
- add
- clear
- contains
- isEmpty
- remove
- size
- get
- Stack
- Queue
- Set, interfaccia implementata da:
- HashSet
- TreeSet
- Map, interfaccia implementata da:
- HashMap
- HashTable
- TreeMap
- clear
- containsKey
- containsValue
get– isEmpty– keySet– put– values
Il metodo contains compara solo i riferimenti degli oggetti contenuti nella struttura dati. Per comparare il contenuto degli oggetti dobbiamo ridefinire il metodo equals (che deve essere una relazione di equivalenza) e il metodo hashCode, entrambi derivati da Object. Quest'ultima è obbligatorio ridefinirla se vogliamo utilizzare HasSet, HashMap e Hashtable e inoltre, se vogliamo ridefinirla, dobbiamo tenere conto di due fattori:
- se viene eseguito sullo stesso oggetto o su oggetti uguali per equals() deve restituire lo stesso hashCode.
- è meglio avere hashCode diversi per oggetti diversi
1.9 Espressioni regolari
Un'espressione regolare è una stringa che indica un pattern in altre stringhe. La classe che le implementa è Pattern di java.util.regex. Pattern si può usare in due modi:
- tramite il metodo statico matches che restituisce true se l'imput fornisce l'espressione regolare passata
per parametro• tramite il metodo compile
, che permette di compilare un’espressione rego-lare per sfruttarla su più stringhe tramite il metodo matcher
Nelle espressioni regolari abbiamo alcuni caratteri speciali:
- \n per il ritorno a capo
- \t per la tabulazione
- \\per \il carattere 5
- . per indicare qualsiasi carattere
- \d per indicare una cifra
- \D per indicare tutti i caratteri che non rappresentano una cifra
- \s per indicare uno spazio bianco
- \S per indicare tutti i caratteri che non rappresentano uno spazio bianco
Tramite l’uso delle parentesi quadre è possibile indicare classi di caratteri. In-oltre abbiamo anche dei quantificatori, che rappresentano quante volte un carat-tere, una classe di caratteri o un gruppo di caratteri si deve ripetere. I gruppidi caratteri indicano più caratteri che vanno trattati come un unico blocco. Leespressioni regolari si usano anche in metodi come replaceAll
e split
di String.
1.10
Streams Uno stream è una lista di elementi che, anziché essere inserita in una struttura dati, viene vista come un flusso di elementi, sui quali si possono applicare delle operazioni, ad esempio:- forEach
- map
- collect
- filter
- mapToInt
- average
- orElseThrow
- sum
- sorted
- distinct
- limit
carattere per volta. Tutte le classi estendono Reader o Writer, ad esempio FileReader e FileWriter per i file.
1.13.3 Buffered e unbuffered
Tutte le classi che abbiamo visto ora accedono al file ad ogni operazione, rendendo l'accesso molto costoso: sono infatti unbuffered. Per rendere queste operazioni più veloci si usano dei buffer in memoria rendendo le operazioni buffered.
Per rendere la lettura di caratteri più efficiente ad esempio abbiamo BufferedReader e BufferedWriter.
1.13.4 letture e scritture ad alto livello
Con i metodi che abbiamo visto ora possiamo leggere/scrivere un byte alla volta, e inoltre sono error-prone. Per semplificare questi processi, soprattutto con file testuali si usano classi più ad alto livello. Per esempio la classe Files che permette di leggere e scrivere in maniera semplice con i file. Inoltre, per questioni di compatibilità, java rende anche più semplice arrivare alla locazione di un file grazie a attributi come File.separator. Inoltre, se
abbiamo specificato dei file risorsa, è molto semplice trovarli con il metodo getResource
e getFile
.
Interfacce grafiche
Pattern MVC
Per organizzare meglio il codice e non confondere le sezioni che riguardano ambiti diversi, quando si programmano interfacce grafiche è bene separare il codice in:
- codice relativo alla logica di business
- codice relativo alla realizzazione dell'interfaccia
- codice relativo all'interazione con gli utenti
Per fare ciò ci viene in aiuto il Pattern MVC (Model - View - Controller) dove:
- il model rappresenta i dati, la logica dell'applicazione e il meccanismo di persistenza (logica di business)
- la view è il codice dell'interfaccia
- i controller fanno da intermediari tra model e view, gestendo l'interazione con gli utenti
Classi singleton
Sono classi singleton tutte quelle classi di cui esiste un'unica istanza all'interno della classe stessa. Per poterle ottenere bisogna:
rendere privati i costruttori• avere un metodo statico che restituisce l’istanza della classe.
In base a quando avviene l’istanziazione abbiamo due tipi di classi singleton:
- Early istantiation: l’istanza viene creata al caricamento della classe
- Lazy istantiation: l’istanza viene creata al momento che viene richiamatala prima volta.
Sono molto utili per esempio per regolare l’accesso ad una risorsa.
2.3 Java Swing e AWT
Librerie grafiche per la creazione di interfacce.
2.3.1 Container
Sono i componenti base che conterranno tutti gli altri componenti. Ci sono due tipi di container:
- container top-level: sono le finestre del programma. è obbligatorio almeno averne uno per programma(JFrame o JApplet). Inoltre permettono di avere delle finestre di dialogo(JDialog). Sono a sua volta formati da:
- root pane: lo strato che si occupa di gestire gli altri
- layered pane: lo strato che racchiude content pane e barra dei menu
pane: contiene tutte le componenti che stanno in questo container - glass pane: uno strato invisibile posto sopra tutti gli altri. Qualunque cosa disegnata qui viene vista sopra tutti gli altri componenti.
- altri container: la cui presenza non è obbligatoria. Abbiamo:
- JPanel
- JTabbedPane
- JScrollPane
- JSplitPane
I container possono inoltre avere diversi layout, gestiti da altrettante classi:
- BorderLayout
- BoxLayout
- FlowLayout
- GridLayout
2.3.2 Controlli Grafici
Le librerie Swing e AWT mettono a disposizione diversi componenti grafici che possono essere utilizzati nelle interfacce:
- JLabel
- JButton
- JCheckBox
- JRadioButton
- JTextField
- JPasswordField
- JTextArea
- JComboBox
- JList
- JColorChooser
- JFileChooser
- JTable
- JProgressBar
- JSeparator
- JMenuBar
- JPopupMenu
Inoltre è possibile usare java per riprodurre audio.
2.3.3 Gestione degli eventi in java
In java swing e Awt gli eventi si dividono tra tre componenti: - event source: il componente che ha generato l'evento - event object: l'oggetto stesso che rappresenta l'evento e ne descrive le proprietà - event listener: il componente che sta in attesa degli eventi e che è dedicato alla gestione di un particolare evento. Le classi e le interfacce che rappresentano gli eventi sono: - ActionEvent: ev