La paninoteca Mi resta da scrivere solo costo()
La paninoteca Usiamo l ereditarietà per definire dei Panini particolari Ci sono alcuni tipi di pane Estendendo Panino scrivo meno codice Nell esempio eredito descrivi() nelle sottoclassi I panini si possono imbottire a piacimento Ho molte farciture Ogni panino ha un costo diverso A seconda del Pane A seconda di come lo farcisco
Troppe Classi Panino Focaccia Rosetta Toast Ciriola RosettaProsciuttoEMozzarella CiriolapomodoroeMozzarella FocacciaProsciuttoEMozzarella CiriolaAlSalame FocacciaAlProsciutto ToastProsciuttoEFormaggio FocacciapomodoroEMozzarella CiriolaAlProsciutto
È un problema ricorrente A chi interessa?? Capita in molti ambiti: Se vogliamo realizzare la paninoteca aggiungendo ingredienti ai panini Se vogliamo modificare gli stream di comunicazione, come il buffering degli stream Nella realizzazione delle finestre dei programmi a cui vogliamo aggiungere features
Decoratore
class Panino{ costo(){ Is a e Has a class PaninoRipieno extends Panino{ Panino p costo(){p.costo()
Cosa è il decoratore Una classe che si finge un altra La eredita e la contiene Cosa sappiamo Hanno lo stesso supertipo dell oggetto che decora Si possono concatenare Possiamo usare il decoratore al posto dell oggetto il decoratore ha lo stesso supertipo dell oggetto che decora Il decoratore aggiunge qualcosa e delega il resto dei compiti all oggetto che decora Non vuole estendere la superclasse La estenderanno le sue sottoclassi
Concatenare i decoratori Ogni funzione richiama quella dell oggetto contenuto E gli aggiunge qualcosa Prosciutto Mozzarella Pomodoro Rosetta costo() costo() costo() costo()
costo(){ // Pre processing p.costo(); // Post porcessing Ma p.costo è costo(){ // Pre processing p.costo(); // Post porcessing Esempio
Stream Traduzione: Flusso Un programma che deve comunicare apre uno STREAM Le informazioni vengono trasmesse sequenzialmente! Con chi comunico? un file le memoria un socket
Esempio Leggere due byte da tastiera public static void leggi(){ byte b = (byte) System.in.read(); char c = (char) System.in.read(); System.in estende classe astratta InputStream
InputStream Un concetto astratto di lettura di uno stream di byte in sequenza Ho diverse realizzazioni pratiche che differiscono per sorgente di dati ByteArrayInputStream array di byte FileInputStream file esterno PipedInputStream un altro processo SequenceInputStream ObjectInputStream AudioInputStream Sono tutte sottoclassi di InputStream Il mio programma è indipendente dalla sorgente
Problema Ho diversi mezzi di comunicazione Con cui dialogo per mezzo di stream System.in, FileInputStream, Etc. Ho spesso la necessità di modificare il modo con cui leggo o scrivo Da byte a caratteri Da stream a righe Da byte a tipi di dato (int, double) Etc.
FilterInputStream Mi servono delle funzionalità indipendenti dalla sorgente dei dati Buffering, numerazione delle linee, controllo, etc. Queste funzioni sono definte come sottoclassi di FilterInputStream FilterInputStream è una sottoclasse di InputStream FilterInputStream contiene un oggetto di tipo InputStream FilterInputStream può sostituire InputStream e modificare lo stream Ci troviamo difronte ad un Decoratore
Decoratori di stream
UpperCaseInputStream public class UpperCaseInputStream extends FilterInputStream{ public UpperCaseInputStream (InputStream i){ super(i) public int read() throws IOException{ int c = super.read(); return Character.toUpperCase((char) c); InputStream in = new UpperCaseInputStream( new FileInputStream( pippo.txt ));
Gerarchia di Byte Stream
Esempio: Copiare File import java.io.*; public class CopyFile { public static void main(string[] args) { File inputfile = new File( input.txt ); File outputfile = new File("output.txt"); FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outputFile); int c; while ((c = in.read())!= -1){ out.write(c); in.close(); out.close();
Stream di caratteri
Reader e Writer Reader e Writer Le due superclassi astratte per i character stream flussi di caratteri Hanno la caratteristica di obbligare le sottoclassi a leggere e scrivere dividendo i dati in pezzi di 16 bit compatibili con il tipo char Le sottoclassi di Reader (e Writer) implementano stream speciali Alcune hanno il ruolo di ConcreteComponent possono attaccarsi ad una fonte (o ad un destinazione) e leggere (o scrivere) In modo sequenziale con i metodi read() (o write()) Ereditati da Reader (o Writer).
Gestire uno Stream Per l input bisogna: 1. aprire lo stream 2. leggere tutte le informazioni dallo stream fino a quando non terminano 3. chiudere lo stream Per l output bisogna: 1. aprire lo stream 2. scrivere tutte le informazioni tramite lo stream fino a quando non terminano 3. chiudere lo stream
Esempio public class KeyboardInput { public static void main (String args[]) { String stringa = null; InputStreamReader isr = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(isr); stringa = in.readline(); System.out.println("Hai scritto: " + stringa); in.close();
I/O di Dati Lettura e Scrittura di tipi di dati primitivi agganciata a uno stream elementare new DataOutputStream(new FileOutputStream( prova.txt")) readboolean() writeboolean() readbyte() writebyte() readchar() writechar() readdouble() writedouble() readfloat() writefloat() readint() writeint()
I/O di Oggetti Per leggere/scrivere un oggetto occorre poter: a) ricostruire lo stato (tutte le variabili dell oggetto) b) avere informazioni sulla classe c) avere i riferimenti agli oggetti collegati La lettura e la scrittura di queste informazioni si chiama serializzazione degli oggetti. Un oggetto può essere serializzato se implementa l interfaccia Serializable.
I/O di Oggetti : EX import java.io.* Import java.util.date FileOutputStream out = new FileOutputStream("theTime"); ObjectOutputStream s = new ObjectOutputStream(out); s.writeobject("today"); s.writeobject(new Date()); FileInputStream in = new FileInputStream("theTime"); ObjectInputStream s = new ObjectInputStream(in); String today = (String)s.readObject(); Date date = (Date)s.readObject();