Programmazione
ad Oggetti
AA 2011– 2012
Contenuti del corso
• Modulo A
 Tecniche di programmazione
• Docente: Prof. Michele Bugliesi
• Modulo B
 Tecniche di progetto
• Docente: Prof. Alessandro Roncato
Contenuti del corso – Modulo A
1. Introduzione: tipi di dato, oggetti, classi e metodi
2. Progetto e implementazione di classi
meccanismi di encapsulation
3. Interfacce ed ereditarietà
polimorfismo
4. Programmazione parametrica
strutture dati e classi collezione
5. Programmazione ad eventi
Contenuti del corso – Modulo B
1. Design patterns
2. Casi di studio di progettazione
3. Esemi di implementazione
Libri di testo
• Java Concepts.
Cay Horstmann. Wiley & Sons
 Disponibile anche in Italiano: Concetti di
Informatica e Fondamenti di Java APOGEO
• Applying UML and patterns.
Craig Larman. Pearson Education.
 Disponibile anche in Italiano
Slides del corso
 Disponibili on line
 http://www.dsi.unive.it/~po
 Utili per prendere appunti a lezione
 NON sono un libro di testo
 NON sono sufficienti per preparare l’esame
Valutazione
• Esame scritto (50%)
 Copre l’intero programma (mod A + mod B)
• Progetto (30%)
 Individuale, in Java
 Dalla specifica funzionale all’implementazione
• Esercitazioni a casa (20%)
 Individuali
Il corso on-line
• Informazioni e news sulla pagina web
http://www.dsi.unive.it/~po
TM
Java
L’ambiente di
programmazione
JavaTM
• Alto livello
 No puntatori, no gestione esplicita della
memoria (free/malloc)
• Espressivo
 Facilmente estendibile con nuovi tipi di dato,
ricca collezione di tipi nelle librerie
• Portabile:
 bytecode eseguibile su JVM
• Robusto
 controllo dei tipi forte, analisi di sicurezza
JavaTM – nato per la rete
Versioni di JavaTM
Versione
Anno
Novità
1.0
1996
Prima versione
1.1
1997
Classi interne
1.2
1998
Swing e Collections
1.3
2000
Nuovo compilatore
1.4
2002
Asserzioni
1.5
2005
Generics, auto-boxing, for loops
1.6
2006
Aggiornamento delle Librerie
1.7
2011
Aggiornamenti Linguaggio, Librerie, VM
La piattaforma JavaTM
Compilazione ed Esecuzione
Sorgente
Bytecode
A.java
A.class
Una vecchia conoscenza . . .
1: public class HelloWorld
2: {
3:
public static void main(String[] args)
4:
{
5:
// Scrivi in output un saluto
6:
7:
System.out.println("Hello, World!");
8:
}
9: }
Il cuore del programma
• Una chiamata di metodo
Compilazione ed esecuzione
• Compilazione
 javac HelloWorld.java
• Se ha successo crea il file
 HelloWorld.class
• Esecuzione
 java HelloWorld.class
• Output
 Hello World!
JVM – Java Virtual Machine
• Una macchina astratta:
 esegue codice intermedio (bytecode)
 specifica (istruzioni, registri, heap,…)
indipendente dall’architettura sottostante
• Indipendente dal sistema operativo
• Presente nei browser più diffusi
• Implementazioni specifiche per smart card,
palmari, cellulari (KVM) …
Java Virtual Machine
JVM
Class Loader
Bytecode Verifier
Security Manager
• CLASS LOADER
carica in memoria tutte le classi
necessarie al programma (anche
quelle delle librerie usate)
• BYTECODE VERIFIER
Controlla l’integrità degli accessi in
memoria, verifica l’aderenza alla
specifica della JVM, …
• SECURITY MANAGER
Interpreter
verifica la sicurezza delle classi
caricate a run time, controlla gli
accessi ai file, …
JAVA
IL LINGUAGGIO
Tipi e variabili
• Ogni valore nel linguaggio ha un tipo
• Ogni variabile deve essere dichiarata ed
associata ad un tipo:
String greeting = "Hello, World!";
PrintStream printer = System.out;
int luckyNumber = 13;
• Il tipo determina quali sono le operazioni
legali sui valori (e le variabili)
• Variabili di un tipo possono solo assumere
valori di quel tipo
Controllo dei tipi forte
• Il compilatore controlla che il programma
rispetti strettamente tutte le regole
 controlla l’uso dei cast
• I programmi che superano i controlli del
compilatore non causano errori nelle
operazioni sui dati
Oggetti e classi
OGGETTI
• Le strutture dati complesse di un programma
 in C: structs, unions e arrays
 In Java: oggetti (arrays inclusi)
• Generalizzazione delle struct di C
 campi: struttura dell’ggetto
 metodi: operazioni sui campi
CLASSI
 Descrivono la struttura dei campi
 Definiscono l’implementazione dei metodi
 Sono i tipi degli oggetti
Oggetti e classi
• Ogni oggetto appartiene ad una classe.
• un oggetto di classe PrintStream
Due oggetti di tipo String
• Ogni oggetto ha una copia privata dei suoi campi
campo
campo
• Tutti gli oggetti di una classe condividono lo stesso
codice dei metodi
Oggetti di classe Rectangle
• Classe definita nella libreria java.awt
• Descrive la struttura di un rettangolo
posizionato sul piano cartesiano
(x,y) = posizione origine:
angolo in alto a sinistra
campi privati
dell’oggetto
Costruttori
new Rectangle(5, 10, 20, 30)
•
Il costrutto new invoca il costruttore, per
allocare nuovo oggetto di tipo Rectangle


•
Il nome del costruttore coincide con il nome
della classe
Usa i parametri (5, 10, 20, e 30) per
inizializzare i dati dell’oggetto
Restituisce un riferimento all’oggetto
Rectangle box = new Rectangle(5, 10, 20, 30);
Costruttori
• Una classe può fornire più di un costruttore
• Overloading
• Diverse modalità di creazione di oggetti
Rectangle box1 = new Rectangle(5, 10, 20, 30)
Rectangle box2 = new Rectangle()
// costruisce un rettangolo con origine (0,0)
// larghezza 0, e altezza zero 0
Sintassi: new
new ClassName(parameters)
Esempi:
new Rectangle(5, 10, 20, 30)
new Rectangle()
• Costruisce un nuovo oggetto, inizializza lo
stato con i parametri, e restituisce un
riferimento all’oggetto costruito.
Metodi
• Realizzano le operazioni supportate dagli
oggetti
• Definiti dalla classe
 Classe definisce l’implementazione
 Descrive la firma visibile all’esterno
• Invocazione
 Deve indicare l’oggetto “target”
oggetto.metodo(argomenti)
Continua…
Metodi della classe PrintStream
Metodi della classe String
• toUpperCase: crea un altro oggetto di tipo
String che contiene i caratteri della stringa
originaria, ma convertiti in maiuscolo
String fiume = "Mississippi";
String fiumeInUpperCase = fiume.toUpperCase();
// fiumeInUpperCase = "MISSISSIPPI"
Continua…
Metodi della classe String
• length(): conta il numero di caratteri della
stringa
Oggetto
Metodo
String greeting = new String("Hello, World!“);
int n = greeting.length(); // n = 13
(new String(“pippo”)).toUpperCase()
Oggetto
Metodo
Domande
•
Quale è la sequenza di istruzioni per calcolare la
lunghezza della stringa “Arcobaleno”?
•
Quale è la sequenza di istruzioni per stampare la
versione uppercase della stringa "Hello,
World!"?
•
È legale la seguente sequenza di istruzioni?
String fiume = "Mississippi";
fiume.println();
Perché o perché no?
Risposte
•
new String(“Arcobaleno“).length()
•
System.out.println(“Hello World”.toUpperCase());
•
Non è legale: la variabile fiume ha tipo
String e la classe String non definisce
il metodo println()
Controllo di tipi forte
• La classe di un oggetto definisce quali
metodi si possono invocare sugli oggetti
della classe
• Il compilatore controlla che le invocazioni
rispettino la dichiarazione della classe
System.out.length(); // ERRORE DI TIPO (COMPILE-TIME)
Controllo di tipi forte
• La classe di un oggetto definisce quali
metodi si possono invocare sugli oggetti
della classe
• I metodi di un oggetto sono l’unico modo per
agire sui campi dell’oggetto
Rectangle box = new Rectangle(5,10,20,20).
System.out.println(box.width); // ERRORE DI TIPO
Metodi della classe Rectangle
• getWidth(): restituisce il valore che
corrisponde alla base del rettangolo
Rectangle box = new Rectangle(5,10,20,20).
System.out.println(box.width); // ERRORE DI TIPO
System.out.println(box.getWidth()); // OK
Continua…
Metodi della classe Rectangle
• Translate(): modifica l’oggetto su cui viene
invocato, traslando di x a destra, e di y verso il
basso
box.translate(x, y);
• Mutators: metodi con side effects per modificare
i valori dei campi
Continua…
Metodi e side-effects
box.translate(15, 25);
Oggetti e riferimenti
• Un riferimento è una astrazione del puntatore
ad un oggetto
• La creazione di un oggetto con new restituice
un riferimento al nuovo oggetto
Rectangle box = new Rectangle();
• Diverse variabili di tipo oggetto possono
condividere lo stesso riferimento
Rectangle box = new Rectangle(5, 10, 20, 30);
Rectangle box2 = box;
Continua…
Assegnamento
• Il comportamento dell’operazione di
assegnamento varia a seconda del tipo della
variabile (e quindi del valore) coinvolto.
• L’assegnamento su variabili di tipo primitivo
ha un effetto diverso dall’assegnamento su
variabili di tipo oggetto
Variabili di tipo primitivo
Contengono valori del loro tipo
Variabili di tipo oggetto
Contengono riferimenti ad oggetti, non oggetti
Assegnamento su tipi primitivi
•
int luckyNumber = 13;
int luckyNumber2 = luckyNumber;
luckyNumber2 = 12;
Due variabili, due valori distinti
Assegnamento su tipi oggetto
•
Rectangle box = new Rectangle(5, 10, 20, 30);
Rectangle box2 = box;
box2.translate(15, 25);
Due variabili, stesso
riferimento
Continua…
Programmi e classi applicazione
Un programma è costituito da più classi
• Classe applicazione: contiene il main
 al più una classe applicazione in un
programma
• Il main avvia la computazione
 costruisce uno o più oggetti delle del
programma
 Invoca i metodi su tali oggetti
 Stampa i risultati
File RectangleApp.java
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
import java.awt.Rectangle;
public class RectangleApp
{
public static void main(String[] args)
{
Rectangle box = new Rectangle(5, 10, 20, 30);
// Sposta il rettangolo
box.translate(15, 25);
// Stampa nuove info
System.out.println(“Origine dopo la traslazione:”);
System.out.println(box.getX());
System.out.println(box.getY());
}
}
Classi di libreria
• Sempre includere le classi di libreria
utilizzate dall’applicazione
 classi delle librerie raggruppate in packages
 Importiamo le classi specificando i nomi di
package e di classe
import java.awt.Rectangle;
 Le classi del package java.lang (ad
esempio String e System)sono importate
automaticamente
Classi di libreria
import packageName.ClassName;
Esempio:
import java.awt.Rectangle; // importa la classe Rectangle
import packageName.*;
Esempio:
import java.util.*; // importa tutte le classi del package
Import in Java ~ #include in C
Librerie – Documentazione
• API: Application Programming Interface
• Include la descrizione delle classi e dei relativi
metodi della (fornitissima!) libreria Java
• http://java.sun.com/j2se/1.5/docs/api/index.html
• http://java.sun.com/j2se/1.6/docs/api/index.html
Documentazione sulle API
La API della classe Rectangle
Javadoc Method Summary
Documentazione del metodo translate
Domande
•
Quali sono gli errori nei seguenti
frammenti di codice?
•
•
•
Rectangle r = (5,10,15,20)
Double w = Rectangle().getwidth();
Rectangle r; r.translate(5,10);
Risposte
• Manca il costruttore
• Manca new
• r non è inizializzato
Esempio: Tombola!
• Vogliamo progettare una applicazione che
realizza il gioco della tombola
• Versione semplificata: un banco, un
giocatore, ogni giocatore una scheda
• Ci vengono già fornite le classi necessarie
 Banco
 Giocatore
Banco
• Costruttore:
 Banco()
crea una nuova istanza della classe
• Metodi:
 int estraiNumero()
restituisce un numero nell’intervallo [1..90]
(ad ogni chiamata genera un numero diverso)
Giocatore
• Costruttore
 Giocatore(String nome)
crea un giocatore, con il nome indicato ed una
sola scheda
• Metodi:
 void controllaNumero(int x)
controlla se il numero è contenuto nella sua
scheda; se si lo “marca”
Giocatore
• Metodi:
 boolean tombola()
restituisce true quando tutti i numeri della sua
scheda sono “marcati”
 Integer[] verifica()
restituisce un array che contiene i numeri
della sua scheda
Integer è un tipo reference isomorfo al tipo int
Tombola
• La classe applicazione che realizza il gioco:
 crea un banco ed un giocatore
 esegue un ciclo in cui ad ogni iterazione in
banco estrae un numero, il giocatore lo
controlla e controlla se ha completato la sua
scheda
 il ciclo termina non appena il giocatore
completa la sua scheda
 All’uscita dal ciclo stampa i numeri della
scheda del giocatore
Tombola
public class Tombola
{
public static void main(String[] args)
{
Banco b = new Banco();
Giocatore g = new Giocatore(“Mario”);
while (true) {
int x = b.estraiNumero();
System.out.println(“Numero estratto = ” + x);
g.controllaNumero(x);
if (g.tombola()) break;
}
Integer[] scheda = g.verifica();
for (int i = 0; i < scheda.length; i++)
System.out.println(scheda[i])
}
}
NOTE
• Nessuna informazione data sulla struttura
interna degli oggetti in gioco
• Conosciamo i metodi che essi forniscono
 notare bene: conosciamo la specifica dei
metodi, non come sono implementati
• E’ tutto quello che serve per programmare
l’applicazione
• La chiave del concetto di encapsulation
Oggetti / Encapsulation
• Oggetti
 esportano la specifica dei propri metodi
• interfaccia pubblica che definisce l’interazione
tra oggetti e codice “cliente”
 mascherano la propria struttura interna
(i campi) e l’implementazione dei metodi
• Codice cliente
 indipendente dall’implementazione degli
oggetti
Esercizio
• Create una versione della tombola in cui
possono giocare più giocatori
 Il gioco termina non appena uno dei giocatori
completa la sua scheda
Metodi e argomenti
• Argomenti = dati in input per i metodi
• Non tutti i metodi hanno argomenti
box.translate(10,15)
box.getwidth() // no parametri espliciti
• Tutti i metodi hanno un argomento implicito:
l’oggetto su cui il metodo viene invocato
box.getwidth();
Continua…
Elementi di
programmazione grafica
• Introduzione alle applicazione grafiche
 contesto grafici
 forme geometriche elementari
 colori
 “input dialogs” per ottenere input dall’utente
• Frames e applets
Frames
•
La classe JFrame
JFrame frame = new JFrame();
frame.setSize(300, 400);
frame.setTitle(“An Empty Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
•
import javax.swing.*;
Frames
File EmptyFrameViewer.java
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
import javax.swing.*;
class EmptyFrameViewer
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
final int FRAME_WIDTH = 300;
final int FRAME_HEIGHT = 400;
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle(“Un frame vuoto");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Domande
1. Come dobbiamo modificare
EmptyFrameViewer per ottenere un frame
quadrato con titolo "Hello, World!"?
2. Come scriviamo un programma che lancia
due frames?
Risposte
1. Modifca EmptyFrameViewer come segue:
frame.setSize(300, 300);
frame.setTitle("Hello, World!");
2. Costruisci due oggetti JFrame definendone
la dimensione e poi invoca
setVisible(true) su ciascuno
Disegno di forme geometriche
• JComponent
 La classe che definisce contenitori
generici, al cui interno includiamo
forme geometriche
• Possiamo definire nuovi JComponent
class ShapeComponent extends JComponent
{
. . .
}
Disegno di forme geometriche
• paintComponent
 metodo che produce il disegno
 invocato (automaticamente) tutte le volte che
il componente per il quale è definito viene
ridisegnato
Disegno di forme geometriche
• paintComponent(Graphics g)
 g contesto grafico
 Graphics classe che permette di manipolare
lo stato del contesto grafico
class ShapeComponent extends JComponent
{
public void paintComponent(Graphics g)
{
// Converti in Graphics2D
Graphics2D g2 = (Graphics2D) g;
. . .
}
}
Disegno di forme geometriche
• Graphics2D estende Graphics con metodi
per il rendering in due dimensioni
• Ad esempio:
// g2: Graphics
Rectangle rect = new Rectangle(5, 10, 20, 30);
g2.draw(rect);
• package java.awt
File ShapeComponent.java
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
import
import
import
import
import
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Rectangle;
javax.swing.JPanel;
javax.swing.JComponent;
/**
Un Component che disegna due rettangoli.
*/
class ShapeComponent extends JComponent
{
public void paintComponent(Graphics g)
{
// Ottieni un graphics2D
Graphics2D g2 = (Graphics2D) g;
Continua…
File ShapeComponent.java
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27: }
// Costruisci un rettangolo e disegna
Rectangle r = new Rectangle(5, 10, 20, 30);
g2.draw(r);
// Trasla il rettangolo (15 a dx, 25 in basso)
r.translate(15, 25);
// Disegna il rettangolo traslato
g2.draw(r);
}
Applicazioni
• ShapeViewer
 classe che lancia una finestra all’interno della
quale vengono raffigurate Ie componenti
 L’applicazione è costruita interamente
all’interno del metodo main della classe
 Disegna due rettangoli
Continua…
Applicazione ShapeViewer
Il metodo main
1. Costruisci il frame
2. Costruisci un oggetto della classe component
ShapeComponent component = new ShapeComponent();
3. Aggiunti il component al frame
frame.add(component);
La chiamata è leggermente più complicata per
versioni di Java precedenti alla 5:
frame.getContentPane().add(component);
4. Rendi visibile il frame
File ShapeViewer.java
01: import javax.swing.JFrame;
02:
03: class ShapeViewer
04: {
05:
public static void main(String[] args)
06:
{
07:
JFrame frame = new JFrame();
08:
09:
final int FRAME_WIDTH = 300;
10:
final int FRAME_HEIGHT = 400;
11:
12:
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
13:
frame.setTitle(“Two Rectangles");
14:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
15:
Continua…
File ShapeViewer.java
16:
17:
18:
19:
20:
21: }
ShapeComponent component = new ShapeComponent();
frame.add(component);
frame.setVisible(true);
}
Domanda
3. Che succede se sostituiamo la chiamata
g2.draw(box)con g.draw(box) ?
Risposta
3. Il compilatore segnala un errore
g : Graphics non ha un metodo draw
Applets
• Applets sono applicazioni eseguite
all’interno di un browser
• L’implementazione di una Applet utilizza il
pattern seguente:
public class MyApplet extends JApplet
{
public void paint(Graphics g)
{
// Ottieni un contesto grafico
Graphics2D g2 = (Graphics2D) g;
// Istruzioni per il disegno
. . .
}
}
Applets
•
Struttura molto simile a quella di un
JComponent, con due differenze:
1. Estende JApplet, invece di JComponent
2. codice del disegno incluso nel metodo
paint, invece che nel metodo
paintComponent
File ShapeApplet.java
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
import
import
import
import
java.awt.Graphics;
java.awt.Graphics2D;
java.awt.Rectangle;
javax.swing.JApplet;
/**
Un applet che disegna due rettangoli.
*/
public class ShapeApplet extends JApplet
{
public void paint(Graphics g)
{
// Ottieni un contesto grafico
Graphics2D g2 = (Graphics2D) g;
Continua…
File ShapeApplet.java
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27: }
// Costruisci un rettangolo e disegna
Rectangle r = new Rectangle(5, 10, 20, 30);
g2.draw(r);
// Trasla il rettangolo (15 a dx, 25 in basso)
r.translate(15, 25);
// Disegna il rettangolo traslato
g2.draw(r);
}
Applets
• Esecuzione
 creare un file HTML ed inserire il codice che
lancia l’applet mediante la tag applet
 Un file HTML può contenere diverse applets,
ciascuno delle quali introdotta da una
corrispondente tag (di tipo applet)
• Una applet può essere lanciata mediante
l’appletviewer, o all’interno di un browser
appletviewer RectangleApplet.html
File RectangleApplet.html
<html>
<head>
<title>Due rettangoli</title>
</head>
<body>
<p>Here’s my first applet:</p>
<applet code="RectangleApplet.class" width="300" height="400">
</applet>
</body>
</html>
Applets
Forme Geometriche
• Rectangle, Ellipse2D.Double,
Line2D.Double (package java.awt.geom)
• Alcune classi, e.g. Line2D.Double, sono
interne. Per il momento ignoriamo, ma notiamo
la dichiarazione import
import java.awt.geom.Ellipse2D; // no .Double
• Per ottenere una forma dobbiamo costruirla e
disegnarla
Ellipse2D.Double e = new Ellipse2D.Double(x, y, width, height);
g2.draw(e);
Una ellisse e la sua bounding box
Linee
• Due modi per disegnare una linea:
Line2D.Double segmento = new Line2D.Double(x1, y1, x2, y2);
oppure,
Point2D.Double from = new Point2D.Double(x1, y1);
Point2D.Double to = new Point2D.Double(x2, y2);
Line2D.Double segmento = new Line2D.Double(from, to);
Stringhe
g2.drawString("Message", 50, 100);
Basepoint
Domande
4. Quale è la sequenza di istruzioni per
disegnare un cerchio con centro (100, 100)
e raggio 25?
5. Quale è una usequenza di istruzioni per
disegnare la lettera "V" all’origine (0,0)
componendo due segmenti di linea?
6. Quale è la sequenza di istruzioni per
disegnare la stringa costituita dalla lettera
"V" ?
Risposte
4.
5.
6.
g2.draw(new Ellipse2D.Double(75, 75, 50, 50);
Line2D.Double segm1 = new Line2D.Double(0, 0, 10, 30);
g2.draw(segm1);
Line2D.Double segm2 = new Line2D.Double(10, 30, 20, 0);
g2.draw(segm2);
g2.drawString("V", 0, 30);
Colori
• Colori standard Color.BLUE, Color.RED, …
• Nuovi colori: formato rgb settando i valori delle
componenti red, green, blue tra 0.0F e 1.0F
Color magenta = new Color(1.0F,0.0F,1.0F), // F = float
• setColor setta il colore del Graphic Contexts
g2.setColor(magenta);
• Usa il colore con i metodi draw e fill
g2.fill(rectangle); // riempito con il colore corrente
Domanda
7.
Quale è la sequenza di istruzioni per
disegnare un quadrato giallo su uno
sfondo rosso?
Risposta
7.
Disegna un quadrato giallo all’interno di un
quadrato rosso:
g2.setColor(Color.RED);
g2.fill(new Rectangle(0, 0, 200, 200));
g2.setColor(Color.YELLOW);
g2.fill(new Rectangle(50, 50, 100, 100));
Scarica

01Intro