


































Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Concetti di progettazione del software Concetti di programmazione OOP Java JCF Swing
Tipologia: Sintesi del corso
1 / 42
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!



































_ Introduzione alla progettazione del software
_ Classificazione delle applicazioni Rispetto al flusso di controllo
_ Ciclo di vita del software
_ Fattori di qualità del SW ESTERNE Correttezza Affidabilità Robustezza Sicurezza Innocuità Usabilità Estendibilità Riusabilità Interoperabilità
Efficienza Strutturazione Modularità Comprensibilità Verificabilità Manutenibilità Portabilità
_ Correttezza, Affidabilità,Robustezza, Sicurezza, Innocuità
_ Usabilità
_ Estendibilita Facilità con cui il SW può essere adattato a modifiche delle specifiche Nota: Importantissimo in grandi programmi Nota: Due principi per l'estendibilità:
_ Riusabilità Facilità con cui il SW può essere re-impiegato in applicazioni diverse da quella originaria Nota: Evita di reinventare soluzioni Nota: Richiede alta compatibilità
_ Interoperabilità
_ Efficienza
_ Principi per la modularità In sintesi, i quattro dogmi della modularizzazione sono:
_ Concetti di base dell'approccio OO
_ Fattori di qualità influenzati dall'approccio OOP ESTERNE Correttezza Affidabilità Robustezza Sicurezza Innocuità Usabilità Estendibilità favorita dalla ereditarietà Riusabilità favorita dal concetto di classe e di ereditarietà Interoperabilità
INTERNE Efficienza Strutturazione favorita dal concetto di incapsulamento e dalla ereditarietà Modularità favorita dal concetto di classe Comprensibilità favorita dalla struttura vicina al modo in cui vediamo la realtà Verificabilità Manutenibilità Portabilità
JAVA OOP
_ Espressione condizionale Sintassi
(espressione booleana)?
_ Classi associate ai tipi primitivi Per ogni tipo primitivo esiste la corrispondente classe associata (denominata classe wrapper) byte short int long float double char boolean Byte Short Integer Long Float Double Character Boolean
_ Conversione STRING to INT String s = JOptionPane.showInputDialog("Inserisci un numero"); int x = Integer.parseInt(s);
_ Generare numero random int x =(int) (Math.random () * 6 + 1); // numero intero tra 1 e 6
_ Overloading di metodi
_ Passaggio dei parametri •Tipi di dato primitivi passaggio per valore •Riferimenti ad oggetti passaggio per valore (che però è riferimento ad un oggetto su heap)
_ Variabili statiche con valori costanti tipo FINAL public static final tipo nomeVariabile=valore;
Esempio: public class Utilita { public static final int ZERO=0; ...
_ Classi non pubbliche Classi non pubbliche possono essere definite in qualsiasi file che contiene una (e una sola) classe pubblica.
_ Compilare ed eseguire un programma JAVA COMPILARE javac Primo.java
Crea il file Primo.class ESEGUIRE java Primo
_ Inizializzazioni implicite dei campi dati di una classe
_ Custom Exception import java.io.*; class ClasseEcc { void ff() throws IOException { Exception ec = new Exception("Prima eccezione"); InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); int i = Integer.parseInt(br.readLine()); try { if (i == 1) throw ec; throw new Exception("Altra eccezione"); } catch(Exception e) { System.out.println(e.getMessage()); } System.out.println("Prosecuzione della funzione"); } public static void main (String[] args) throws IOException { ClasseEcc ex = new ClasseEcc(); ex.ff(); System.out.println("Prosecuzione del programma"); } }
_ Lanciare eccezioni
Esempio: public class BankAccount { public void withdraw(double amount) { if (amount > balance) throw new IllegalArgumentException(“Saldo insufficiente"); balance = balance - amount; } ... }
La stringa in input al costruttore di IllegalArgumentException rappresenta il messaggio d’errore da associare all’eccezione
_ Segnalare eccezioni
throws public void read(BufferedReader in) throws IOException
Esempio: public class Coin { public void read(BufferedReader in) throws IOException { value = Double.parseDouble(in.readLine()); name =in.readLine(); } ... } La clausola throws segnala al chiamante di Coin.read che esso può generare un’eccezione di tipo IOException
_ Usare le eccezioni di Run Time
_ Custom Exception Example: Divisione per zero public class DivisionePerZeroException extends RuntimeException{ public DivisionePerZeroException() { super("Divisione per zero!"); } public DivisionePerZeroException(String msg) { super(msg); } }
public class Divisione { public Divisione(int n, int d) { num=n; den=d; } public double dividi(){ if (den==0) throw new DivisionePerZeroException(); return num/den; } private int num; private int den; }
public class Test { public static void main(String[] args) throws IOException { double res; Scanner scan = new Scanner(System.in); System.out.print("Inserisci il numeratore:"); int n= Integer.parseInt(scan.nextLine()); System.out.print("Inserisci il denominatore:"); int d= Integer.parseInt(scan.readLine()); try { Divisione div = new Divisione(n,d);
ByteArrayOutputStream FileOutputStream ObjectOutputStream PipedOutputStream FilterOutputStream BufferedOutputStream DataOutputStream PrintStream
Stream di caratteri Reader (Input di caratteri) BufferedReader CharArrayReader InputStreamReader FileReader StringReader PipedReader FilterReader Writer (Output di caratteri) BufferedWriter CharArrayWriter OutputStreamWriter FileWriter StringWriter PipedWRiter FilterWriter PrintWriter
_Example: PrintWriter video = new PrintWriter(System.out); video.println(12); video.println(“Ciao”); video.println(13,56);
_ Lettura/Scrittura file: -FileInputStream -FileOutputStream
-FileReader -FileWriter
_ Livello di logging
_ Derivazione -Tutte le proprietà definite per la classe base vengono implicitamente definite anche nella classe derivata cioè vengono ereditate da quest’ultima. -La classe derivata può avere ulteriori proprietà -Ogni oggetto della classe derivata è anche un oggetto della classe base cioè si può usare un oggetto della classe derivata in ogni situazione/contesto in cui si può usare un oggetto della classe base -Non è vero che un oggetto della classe base è anche un oggetto della classe derivata non è possibile usare un oggetto della classe base laddove si può usare un oggetto della classe derivata. -Una classe derivata può fungere da classe base per ulteriori derivazioni public class B {…} public class D extends B {…} public class E extends D {…} -Una classe può avere un numero qualsiasi di classi derivate public class B {…} public class D extends B {…} public class Dbis extends B {…} -Riferimenti di diverse classi possono denotare lo stesso oggetto WRONG: public class B {…} public class D extends B { int x_d; } … D d = new D(); d.x_d = 10; B b = d; //OK b e d denotano lo stesso ogg. b.x_d = 20; //NO x_d non è un campo di B! //type checking statico CORRECT: public class B {…} public class D extends B { int x_d; } … D d = new D(); d.x_d = 10; B b = d; //OK b e d denotano lo stesso ogg. ((D)b).x_d = 20; //OK (D)b è un riferimento di tipo D
_ this() -da utilizzare in modo analogo a super() -è un’invocazione esplicita ad un altro costruttore della stessa classe -permette si riusare codice già scritto
Example: //File Persona.java public class Persona {
//campi dati (variabili di istanza) private String nome; private String residenza;
//costruttori public Persona() {
Definizione: è una astrazione per un insieme di funzioni pubbliche, delle quali si definisce la segnatura ma non il corpo.
-Una classe implementa l’interfaccia definendo TUTTE le funzioni previste dalla stessa.
_ Summary interface Una interfaccia è simile ad una classe dove non possono essere presenti campi dati (eccetto costanti statiche…). Inoltre tutte le funzioni sono astratte (segnatura, ma non corpo). Le interfacce rappresentano collezioni di funzionalità messe a disposizione dalle classi che le implementano
_ Differenza tra interface e classi abstract -una classe astratta è una classe, cioè una astrazione di un insieme di oggetti simili (quelli delle sue sottoclassi) -una interfaccia è una semplice astrazione di un insieme di funzionalità
_ Altro su interfacce -Una classe può implementare un'interfaccia public interface I { void g(); } public interface J { void h(); }
public class C implements I,J { void g(){…} void h(){…} }
-Una interfaccia può essere derivata da un’altra interfaccia public interface I { void g(); } public interface J extends I {void h();}
public class C implements J { void g(){…} void h(){…} }
-Java supporta ereditarietà multipla per le interfacce (non per le classi) public interface I {void g();} public interface J {void h();} public interface M extends I,J {void k();}
public class C implements M { void g(){…} void h(){…} void k(){…} }
_ Classe Object -Tutte le classi Java sono implicitamente derivate da Object -Tutti gli oggetti, qualunque sia la classe a cui appartengono, sono istanze di Object e ne ereditano le funzioni
_ Funzioni di Object -public String toString(); -Associa all’oggetto di invocazione una stringa stampabile, se ne può fare l'overriding -toString() e derivazione: -nel farne overriding possiamo riusare toString() della classe base -Example: //EsempioToStringDerivata public class B { private int i;
public B(int x) { i = x; } public String toString() { return "i: " + i; } }
public class D extends B { private int j; public D(int x, int y) { super(x); j = y; } public String toString() { return super.toString() + " j: " + j; } }
public class EsempioToStringDerivata { public static void main(String[] args) { D d = new D(5,10); System.out.println(d); } } /* Stampa: i: 5 j: 10 */
-public Final Class getClass(); -public boolean equals(Object o); -protected Object clone(); -public int hashCode(); -etc...
_ La classe Class -Nella JVM esiste implicitamente un oggetto della classe Class per ogni classe (o interfaccia) del programma. C.class Class: Class c = … -Class non ha costruttori accessibili ai clienti
_ La funzione isInstance boolean isInstance (Object o)
_La funzione restituisce true se o denota un oggetto che è istanza della classe (interfaccia) rappresentata dall’oggetto di invocazione. Si usa per verificare se un oggetto è istanza di una classe.
_Example: //EsempioIsInstance
public class B {}
public class D extends B {}
public class EsempioIsIntance1 { public static void main(String[] args) { B b1 = new B(); D d1 = new D(); System.out.println(B.class.isInstance(b1)); //"true" System.out.println(B.class.isInstance(d1)); //"true" System.out.println(D.class.isInstance(d1)); //"true" System.out.println(D.class.isInstance(b1)); //"false" }
-Perché in Java deve valere il seguente vincolo: se o1.equals(o2) allora o1.hashcode()==o2.hashcode() -hashcode() restituisce un intero che deve essere calcolato facendo uso degli stessi campi usati nella verifica di uguaglianza profonda
_ Pattern per l'overriding di hashcode(): public class B { private int x, y; ...
public boolean equals(Object o) { if (o != null && getClass().equals(o.getClass())) { B b = (B)o; //test uguaglianza profonda return (x==b.x) && (y==b.y); //usa i campi x e y } else return false; }
public int hashcode() { return x+37*y; //funzione di hash //basata sui campi x e y } }
_ Overriding di equals() nelle classi derivate: Va effettuato richiamando prima l'equals() della classe base, e poi verificando l'uguaglianza dei campi propri della classe derivata
_ Pattern per l'overriding di equals() nelle classi derivate public class D extends B { private int z; ...
public boolean equals(Object o) { if (super.equals(o)){ D d = (D)o; //test uguaglianza profonda //dei campi propri della classe return z==d.z; } else return false; }
... }
_ Pattern per l'overriding di hashcode() nelle classi derivate public class D extends B { private int z; ... public boolean equals(Object o) { if (super.equals(o)){ //usa campi della classe base D d = (D)o; //test uguaglianza profonda //dei campi propri della classe return z==d.z; //più campi addizionali } else return false; }
public int hashcode() { return super.hashcode()+ //usa campi della classe base 53*z; //più campi addizionali } ... }
_ Copia di Oggetti: Possiamo effettuare una copia superficiale, ovvero una copia dell'identificatore di un oggetto Oppure possiamo effettuare una copia profonda, ovvero creiamo un nuovo oggetto che è un clone dell'oggetto originario (Identico ma con un diverso identificatore)
_ Esempio copia superficiale: public class C {…}
C c1 = new C(4,5); C c2; c2 = c1;
//c1, c2 sono uguali superficialemnte
_ Copia profonda con clone(): //Pattern per l'overriding di clone()
public class B implements Cloneable { private int x, y; ...
public Object clone() { try{ B b = (B)super.clone(); //copia profonda dei campi dati //incluse liste, array, ecc. return b; } catch(CloneNotSupportedException e) { throw new InternalError("..."); } }
... }
Osservazioni: super.clone() è l’invocazione al clone() di Object che crea un nuovo oggetto della stessa classe dell’oggetto di invocazione facendo copia superficiale dei campi dati
Si noti che questo comportamento corrisponde alla copia esatta della porzione di memoria dove è contenuto l’oggetto di invocazione, e non è ottenibile in nessun altro modo!
B b = (B)super.clone(); l’oggetto restituito da clone() è denotato da un riferimento di tipo Object attraverso il casting lo denotiamo con un riferimento del tipo giusto così da potere operare sui suoi campi
//copia profonda dei campi dati //incluse liste, array, ecc. super.clone() ha prodotto una nuovo oggetto con i campi che sono una copia superficiale dei campi dell’oggetto originario se siamo in presenza di campi per rappresentare, liste, array, ecc. dobbiamo farne la
Coppia
_ Tipi Generici Esempio: class C
... C
_ Nome dei parametri generici Per i nomi dei parametri di tipo formali si può utilizzare qualsiasi identificatore valido in Java, tuttavia esistono delle convenzioni che è bene conoscere ed utilizzare:
_ Tipi Generici: Cancellazione
_ Uso di classi Wrapper invece che tipi dato primitivi con Generics:
_ Interfacce del JCF: Collection Set SortedSet NavigableSet List Queue Deque BlockingQueue BlockingDeque
Map ConcurrentMap ConcurrentNavigableMap SortedMap NavigableMap
_ Interfacce e classi del JCF: Collection Set -HashSet -LinkedHashSet SortedSet -TreeSet NavigableSet List -ArrayList -LinkedList -Vector -Stack Queue -PriorityQueue Deque -ArrayDeque BlockingQueue BlockingDeque
Map ConcurrentMap ConcurrentNavigableMap SortedMap NavigableMap
_ Interfaccia Collection: public interface Collection
// Bulk Operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); // Optional boolean removeAll(Collection<?> c); // Optional boolean retainAll(Collection<?> c); // Optional void clear(); // Optional
// Array Operations Object[] toArray();
_ Interfaccia Set: public interface Set
} L'interfaccia Set non definisce alcuna nuova funzione