Sei sulla pagina 1di 4

CLASSE ASTRATTA E INTERFACCIA

Le interfacce e le classi astratte forniscono meccanismi mediante i quali separare l'interfaccia


dall'implementazione.
Queste due tipologie di classe vengono utilizzate, prettamente, per fornire una struttura di base alle classi
derivate da esse. Ovviamente, queste non potranno essere utilizzate per creare un oggetto, ma rimarranno
degli elementi astratti all'interno del programma.

Una classe astratta una classe con uno o pi metodi astratti. Questa permette di creare in una classe,
quindi, uno o pi metodi indefiniti, allo scopo di mettere a disposizione una parte dell'interfaccia, senza la
corrispondente implementazione, che viene poi fatta nelle classi derivate.

Un'interfaccia crea una classe completamente astratta, che consente al programmatore di:
1. stabilire i nomi dei metodi, gli argomenti, i valori di ritorno;
2. non inserire al suo interno il corpo di un metodo;
Realizzare un'interfaccia equivale a stabilire a cosa dovranno somigliare tutte le classi che la
implementano. Pertanto qualsiasi codice utilizzi un'interfaccia, sa quali metodi possono essere richiamati,
ma nient'altro.

Le differenze principali tra queste due tipologie di classe sono:


1. l'interfaccia permette il meccanismo dell'ereditariet multipla, creando una classe che pu essere
oggetto di upcasting a diversi tipi di base;
2. l'interfaccia non pu dichiarare membri e metodi concreti. Ci possibile nelle classi astratte.

FILE
Uno stream I/O rappresenta una sorgente di input o una destinazione di output. Questo pu rappresentare
una moltitudine di tipi di sorgenti e destinazioni, come dischi, memoria,ecc.
Gli Stream supportano molti tipi di dato, dai byte ai tipi primitivi, fino agli oggetti.
Alcuni Stream semplicemente trasmettono dei dati, altri invece trasformano i dati in un modo pi congeniale
all'ultilizzo che si deve fare.

Non importante sapere come uno stream lavori internamente, ci ch importante che lo stream una
sequenza di dati.
Un programma utilizza un input stream per leggere dati da una sorgente, un pezzo alla volta:

Un programma utilizza un output stream per scrivere dati su una destinazione, un pezzo alla volta:
Byte Stream
Si utilizza un byte stream per realizzare input/output con byte di 8 bit. Tutte le classi che operano sugli
stream derivano da InputStream e OutputStream.
ByteStream dovrebbe essere evitato quando si ha a che fare con dei caratteri, in quanto il procedimento
risulterebbe alquanto dispendioso (vedi immagine). Dovrebbe essere invece preferito quando si ha a che
fare con dell'input-output di basso livello.

public class CopyBytes {


public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;

while ((c = in.read()) != -1) {


out.write(c);
}

} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}

Character Stream
La piattaforma Java memorizza i caratteri seguendo le convenzioni Unicode. Gli stream di caratteri
traducono automaticamente questo formato interno da/verso il set di caratteri locale. Questo meccanismo
rende pi facile la internazionalizzazione in quanto il programmatore non deve preoccuparsi del set di
caratteri specifico di un luogo.
Tutte le classi degli stream di caratteri discendono da Writer e Reader. Esempi di queste classi sono quelle
che operano sui file, come FileReader e FileWriter:

public class CopyCharacters {


public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;

try {
inputStream = new FileReader("xanadu.txt");
outputStream = new FileWriter("characteroutput.txt");

int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}

da notare che in CopyCharacters cosy come in CopyBytes si usa un int per scrivere e leggere su/da file.
L'unica differenza che negli stream di byte questo viene memorizzato negli ultimi 8 bit, negli stream di
caratteri negli ultimi 16 bit.

Si pu dire che gli stream di caratteri rappresentano dei wrappers per gli stream di byte. I primi utilizzano
questi ultimi ma operano una traduzione dei byte in caratteri.

Buffered Stream
Se si utilizza un unbuffered I/O ogni chiamata di metodi write e read viene gestita dal Sistema Operativo. Ci
pu rendere meno efficiente un programma perch richiede ripetuti accessi al disco, alla rete ecc.
Per ridurre questo tipo di carico, Java implementa i buffered I/O stream. I bufferedInputStream leggono dati
da un'area di memoria conosciuta come buffer ed il metodo nativo di lettura viene chiamato solo quando il
buffer vuoto. Analogamente, bufferedOutputStream scrive dati su un buffer ed il suo metodo nativo di
scrittura viene chiamato solo quando il buffer pieno.
inputStream =
new BufferedReader(new FileReader("xanadu.txt"));
outputStream =
new BufferedWriter(new FileWriter("characteroutput.txt"));

CONTENITORI
Generalmente i programmi richiedono la creazione di numerosi oggetti i cui criteri saranno noti
solo a tempo di esecuzione. Ci significa che non si conosceranno, a compile-time, ne il tipo ne la
quantit di tali oggetti. Ragion per cui non si pu fare affidamento a referenze di tipo nominativo
(named reference) che si riferiscano a ognuno degli oggetti.
Java offre offre diversi meccanismi per contenere i riferimenti agli oggetti. Il primo contenitore che
ci pu venire in mente l'array, che per ha la limitazione di avere dimensione fissa.
Java offre un insieme di classi contenitore i cui tipi base sono List Set Queue Map. Tra le
molteplici caratteristiche, degno di nota il fatto che gli oggetti di questo tipo si ridimensionano
automaticamente, il che permette di inserire un numero arbitrario di oggetti senza dover specificare
a-priori la dimensione.

Generici [type safe]


Un problema risolto in Java5 quello che prima si permetteva di inserire in una collezione anche
tipi errati. Con i tipi generici ci non pi possibile; il tipo degli oggetti viene dichiarato:

tipoContenitore <tipoOggettiDaContenere> [ArrayList<String>]

Collection: una raccolta sequenziale di singoli elementi,ai quali sono applicate una o pi regole
rappresentanti la politica di gestione di questi.
Collection<Integer> c = new ArrayList<Integer>();

Map: un gruppo di coppie chiave-valore indicanti gli oggetti, che permettono di recuperare un
valore mediante la chiave ad esso associata. Una mappa permette di cercare un oggetto usando
un altro oggetto: chiamato anche array-associativo poich associa oggetti ad altri oggetti.
Map<String,String> map = new HashMap<String,String>();

Iterator: un design pattern molto potente. Viene utilizzato per scorrere un contenitore, di
qualunque tipo esso sia. E' importante nelle situazioni in cui si scritto del codice per un tipo di
contenitore e poi ci si accorge che se ne vuole utilizzare un altro. Quindi permette di poter astrarre
su ogni tipo di collection e ci molto potente.

List <String> s = new List<String>();


Iterator<String> iter = s.iterator();

Con un iteratore non ci si deve preoccupare del numero di elementi presenti nell'array. Ci sono i
metodi hasNext() e next().

Potrebbero piacerti anche