Un oggetto viene inteso come un -...
Transcript of Un oggetto viene inteso come un -...
IL CONCETTO DI OGGETTO Un oggetto viene inteso come un
centro di servizi dotato di una parte visibile (interfaccia) e di una parte nascosta
Centro servizi
Operazione A
Operazione B
Operazione C Parte nascosta
Parte visibile (INTERFACCIA)
IL CONCETTO DI OGGETTO Offre agli altri oggetti (clienti) un
insieme di attività (operazioni) senza che sia nota/accessibile la sua organizzazione interna
Centro servizi
Operazione A
Operazione B
Operazione C Parte nascosta
Parte visibile (INTERFACCIA)
IL CONCETTO DI OGGETTO Ogni cliente può creare (istanziare)
tanti oggetti quanti gliene occorrono a partire da una sorta di “modello” dell’oggetto (classe)
Centro servizi
Operazione A
Operazione B
Operazione C Parte nascosta
Parte visibile (INTERFACCIA)
Classe
SISTEMI A OGGETTI L’architettura di un sistema a oggetti: • un insieme di oggetti che interagi-
scono gli uni con gli altri • senza conoscere nulla delle rispet-
tive rappresentazioni concrete
• Modello di intera- zione a “scambio di messaggi”
L’IDEA DI OGGETTO
• integra dati e elaborazione (comportamento)
• promuove approcci di progettazione e sviluppo sia top-down sia bottom-up
• cattura i principi fondamentali di una corretta strutturazione del software
• introduce una interazione molto ricca e orientata a gestire la complessità
LE PROPRIETÀ DI UN OGGETTO
• Un oggetto possiede stato, funziona-mento e identità
• Struttura e funzionamento di oggetti simili sono definiti nella loro classe comune, di cui essi sono istanze
• I termini istanza e oggetto sono intercambiabili
IL CONCETTO DI CLASSE
• La classe descrive la struttura interna e il funzionamento di un oggetto
• Oggetti appartenenti a una stessa classe hanno: – la stessa rappresentazione interna – le stesse operazioni – lo stesso funzionamento
IL CONCETTO DI CLASSE
Una CLASSE riunisce le proprietà di: • componente software: può essere
dotata di suoi propri dati / operazioni • moduli: incapsula dati e relative
operazioni, fornendo idonei meccanismi di protezione
• tipi di dato astratto: può fungere da “schema” per creare nuovi oggetti
EREDITARIETÀ
• Una relazione tra classi • Una classe condivide la struttura e/o
il funzionamento definito in un’altra classe
• Se la classe B eredita dalla classe A, si dice che B è una sottoclasse di A e che A è una superclasse di B
La nozione di ereditarietà scaturisce dall'esigenza di poter condividere (parti di) una descrizione, cioè di riusare concetti già esistenti e codice già scritto e provato.
IL LINGUAGGIO JAVA • È un linguaggio totalmente a oggetti: tran-
ne i tipi primitivi di base (int, float, ...), esistono solo classi e oggetti
• È fortemente ispirato al C++, ma riproget-tato senza il requisito della piena compati-bilità col C (a cui però assomiglia…)
• Un programma è un insieme di classi • anche il main è definito dentro a una classe!
Java e Classi 11
APPROCCIO JAVA
BYTE-CODE
JAVA
JAVAC Sorgente
Compilatore Byte Code
Rete o File System Loader
Verificatore
Hardware
Interprete Generatore di Codice - Compilatore
Byte Code
CLASSI IN JAVA
Una classe Java è una entità sintatticamente simile alle struct
• però, contiene non solo i dati... • .. ma anche le funzioni che operano su
quei dati • e ne specifica il livello di protezione
– pubblico: visibile anche dall’esterno – privato: visibile solo entro la classe – …
CLASSI IN JAVA Una classe Java è una entità dotata di una "doppia natura": • è un componente software, che in quanto
tale può possedere propri dati e operazioni, opportunamente protetti
• ma contiene anche la definizione di un tipo di dato astratto, cioè uno “stampo” per creare nuovi oggetti, anch'essi dotati di idonei meccanismi di protezione
CLASSI IN JAVA • La parte della classe che realizza il concetto
di componente software si chiama parte statica – contiene i dati e le funzioni che sono propri della
classe in quanto componente software autonomo – questi dati e funzioni devono essere dichiarati static
• L'altra parte della classe, che contiene la definizione di un tipo di dato astratto (ADT) ("schema per oggetti"), è la parte non-statica – contiene i dati e le funzioni che saranno propri degli
oggetti che verranno creati successivamente sulla base di questo "schema"
IL CONCETTO DI CLASSE
Parte STATICA
Definizione ADT
Una classe è un componente software: può avere propri dati (STATICI) e proprie operazioni
(STATICHE)
Una classe contiene però anche la definizione di un ADT, usabile come "schema" per creare poi
nuovi oggetti (parte NON statica)
IL CONCETTO DI CLASSE • Se c'è solo la parte STATICA:
– la classe opera solo come componente software – contiene dati e funzioni, come un modulo – con in più la possibilità di definire l'appropriato
livello di protezione – caso tipico: librerie di funzioni
• Se c'è solo la parte NON STATICA: – la classe definisce semplicemente un ADT – specifica la struttura interna di un tipo di dato,
come le struct – con in più la possibilità di specificare anche le
funzioni che operano su tali dati
PROGRAMMI IN JAVA
Un programma Java è un insieme di classi e oggetti • Le classi sono compo-
nenti statici, che esisto-no già all'inizio del pro-gramma
• Gli oggetti sono invece componenti dinamici, che vengono creati dina-micamente al momento del bisogno
IL PIÙ SEMPLICE PROGRAMMA
• Il più semplice programma Java è dunque costituito da una singola classe operante come singolo componente software
• Essa avrà quindi la sola parte statica
• Come minimo, tale parte dovrà definire una singola funzione (statica): il main
IL MAIN IN JAVA
Il main in Java è una funzione pubblica con la seguente interfaccia obbligatoria:
public static void main(String args[]){ ...... }
• Deve essere dichiarato public, static, void • Non può avere valore di ritorno (è void) • Deve sempre prevedere gli argomenti dalla linea di
comando, anche se non vengono usati, sotto forma di array di String (il primo non è il nome del programma)
CLASSI IN JAVA Convenzioni rispettate dai componenti
esistenti: • il nome di una classe ha sempre l’iniziale
maiuscola (es. Esempio) – se il nome è composto di più parole
concatenate, ognuna ha l’iniziale maiuscola (es. DispositivoCheConta)
– non si usano trattini di sottolineatura
• i nomi dei singoli campi (dati e funzioni) iniziano invece per minuscola
CLASSI E FILE • In Java esiste una ben precisa corrispon-
denza fra – nome di una classe pubblica – nome del file in cui essa dev'essere definita
• Una classe pubblica deve essere definita in un file con lo stesso nome della classe ed estensione .java
• Esempi classe EsempioBase → file EsempioBase.java classe Esempio0 → file Esempio0.java
Java e Classi 22
TIPI DI DATO PRIMITIVI IN JAVA • caratteri
– char (2 byte) codifica UNICODE – coincide con ASCII sui primi 127 caratteri – e con ANSI / ASCII sui primi 255 caratteri – costanti char anche in forma '\u2122'
• interi (con segno) – byte (1 byte) -128 ... +127 – short (2 byte) -32768 ... +32767 – int (4 byte) -2.147.483.648 ... 2.147.483.647 – long (8 byte) -9 1018 ... +9 1018
NB: le costanti long terminano con la lettera L
TIPI DI DATO PRIMITIVI IN JAVA • reali (IEEE-754)
– float (4 byte) - 1045 ... + 1038
(6-7 cifre significative) – double (8 byte) - 10328 ... + 10308
(14-15 cifre significative) • boolean
– boolean (1 bit) false e true – tipo autonomo totalmente disaccoppiato dagli
interi: non si convertono boolean in interi e viceversa, neanche con un cast
– tutte le espressioni relazionali e logiche danno come risultato un boolean, non più un int (come nel linguaggio C)!
ESEMPIO: IL CONTATORE • Questa classe non contiene dati o funzioni
sue proprie (statiche) • Fornisce solo la definizione di un ADT che
potrà essere usata poi per istanziare oggetti
public class Counter { private int val; public void reset() { val = 0; } public void inc() { val++; } public int getValue() { return val; }
}
Dati
Operazioni (comportamento)
Unico costrutto
linguistico per dati e operazioni
Il campo val è privato: può essere acceduto solo dalle operazioni de-finite nella medesima classe (reset, inc, getValue), e nessun altro! Si garantisce l’incapsulamento
OGGETTI IN JAVA • Gli OGGETTI sono componenti “dinamici”:
vengono creati “al volo”, al momento dell’uso, tramite l’operatore new
• Sono creati a immagine e somiglianza (della parte non statica) di una classe, che ne descri-ve le proprietà
• Su di essi è possibile invocare le operazioni pubbliche previste dalla classe
• Non occorre preoccuparsi della distruzione degli oggetti: Java ha un garbage collector!
CREAZIONE DI OGGETTI Per creare un oggetto: • prima si definisce un riferimento, il cui tipo
è il nome della classe che fa da modello • poi si crea dinamicamente l'oggetto
tramite l'operatore new (simile a malloc in C)
Esempio: Counter c; // def del riferimento
... c = new Counter(); // creazione oggetto
La frase Counter c; definisce un riferimento a un (futuro) oggetto di classe Counter
L’oggetto di tipo Counter viene però creato dinamicamente solo in un secondo momento, quando serve, mediante l’operatore new
OGGETTI IN JAVA
Uso: stile a “invio di messaggi” • non una funzione con l'oggetto come parametro… • …ma bensì un oggetto su cui si invocano metodi
Ad esempio, se c è un Counter, un cliente potrà scrivere: c.reset(); c.inc(); c.inc(); int x = c.getValue();
ESEMPIO COMPLETO
public class Esempio1 {
public static void main(String v[]) { Counter c = new Counter(); c.reset(); c.inc(); c.inc(); System.out.println(c.getValue()); } }
• Il main crea un nuovo oggetto Counter… • ... e poi lo usa per nome, con la notazione puntata… • …senza bisogno di dereferenziarlo esplicitamente!
ESEMPIO: COSTRUZIONE • Le due classi devono essere scritte in due
file distinti, di nome, rispettivamente: – Esempio1.java (contiene la classe Esempio1) – Counter.java (contiene la classe Counter)
• Ciò è necessario perché entrambe le classi sono pubbliche: in un file .java può infatti esserci una sola classe pubblica – ma possono essercene altre non pubbliche
• Per compilare: javac Esempio1.java Counter.java
NB: l’ordine non importa
ESEMPIO: COSTRUZIONE • Queste due classi devono essere scritte in
due file distinti, di nome, rispettivamente: – Esempio1.java (contiene la classe Esempio1) – Counter.java (contiene la classe Counter)
• Ciò è necessario perché entrambe le classi sono pubbliche: in un file .java può infatti esserci una sola classe pubblica – ma possono essercene altre non pubbliche
• Per compilare: javac Esempio1.java Counter.java
Anche separatamente, ma nell’ordine: javac Counter.java javac Esempio1.java La classe Counter deve infatti già esistere quando si compila la classe Esempio1
ESEMPIO: ESECUZIONE
• La compilazione di quei due file produce due file .class, di nome, rispettivamente: – Esempio1.class – Counter.class
• Per eseguire il programma basta invocare l’interprete con il nome di quella classe (pubblica) che contiene il main
java Esempio1
GESTIONE DEGLI ERRORI • Spesso vi sono istruzioni “critiche”, che
in certi casi possono produrre errori • L’approccio classico consiste nell’inse-
rire controlli (if… else..) per cercare di intercettare a priori le situazioni critiche
• Ma è un modo di procedere spesso insoddisfacente • non è facile prevedere tutte le situazioni
che potrebbero produrre l’errore • “gestire” l’errore spesso significa solo
stampare a video un messaggio
ECCEZIONI Java introduce il concetto di eccezione • anziché tentare di prevedere le situa-
zioni di errore, si tenta di eseguire l’operazione in un blocco controllato
• se si produce un errore, l’operazione solleva un’eccezione
• l’eccezione viene catturata dal blocco entro cui l’operazione è eseguita…
• … e può essere gestita nel modo più appropriato
ECCEZIONI try { /* operazione critica che può sollevare eccezioni */
} catch (Exception e) { /* gestione dell’eccezione */ }
• Se l’operazione solleva diversi tipi di eccezione in risposta a diversi tipi di errore, più blocchi catch possono seguire lo stesso blocco try
ESEMPIO Conversione stringa / numero • In Java, la conversione stringa / numero
intero è svolta dal metodo statico int Integer.parseInt(String s)
• L’operazione è critica, perché può avvenire solo se la stringa data contiene la rappresentazione di un intero
• Se ciò non accade, parseInt solleva una NumberFormatException
ESEMPIO class EsempioEccezione {
public static void main(String args[]){
int a = 0; String s = "1123";
try { a = Integer.parseInt(s); } catch (NumberFormatException e) { System.out.println("Stringa mal fatta"); } } }
Catturare le eccezioni è spesso importante: un’eccezione non catturata si propaga verso l’esterno, di blocco in blocco: se raggiunge il main, provoca l’aborto del programma
COS’È UNA ECCEZIONE in JAVA • Una eccezione è un oggetto, istanza di java.lang.Throwable o di una sua sottoclasse.
• Le due sottoclassi più comuni sono java.lang.Exception e java.lang.Error
• La parola “eccezione” è però spesso riferita a entrambe
COS’È UNA ECCEZIONE • Un Error indica problemi relativi al
caricamento della classe o al funzio-namento della macchina virtuale Java (es. not enough memory), e va conside-rato irrecuperabile: perciò non dovrebbe essere catturato
• Una Exception indica invece situazioni recuperabili, almeno in linea di principio (fine file, indice di un array oltre i limiti, errori di input, etc.): andrebbe catturata e gestita
ARRAY IN JAVA • Gli array Java sono oggetti, istanze di una
classe speciale denotata da [ ] • Quindi, prima si definisce un riferimento... int[] v; int v[]; Counter[] w; Counter w[];
• …e poi si crea dinamicamente l’oggetto: v = new int[3]; w = new Counter[8];
La posizione delle [] è a scelta: o dopo il nome, come in C, oppure di seguito al tipo (novità)
È un riferimento, quindi non deve specificare alcuna dimensione!
La dimensione si specifica all’atto della creazione
ARRAY IN JAVA Attenzione!! Ogni elemento dell’array: • è una variabile, se gli elementi dell’array sono
di un tipo primitivo (int, float, char, …) v = new int[3];
• è un riferimento a un (futuro) oggetto, se gli elementi dell’array sono (riferimenti a) oggetti
w = new Counter[3]; Inizialmente tutti null
ARRAY IN JAVA Quindi nel primo caso, array di valori primitivi in questo caso, ogni elemento dell’array è una normale variabile, “già usabile” così com’è:
v = new int[3]; v[0] = 1; v[1] = 34;
1 34 v
ARRAY IN JAVA Se trattiamo riferimenti ad altri oggetti • nel secondo caso, invece, ogni elemento
del’array è solo un riferimento: se si vuole un nuovo oggetto, bisogna crearselo!
w = new Counter[3]; w[0] = new Counter(11);
w
11 (nuovo Counter)
Inizialmente tutti null
ARRAY IN JAVA • In quanto istanze di una classe “array”, gli
array Java hanno alcune proprietà • Tra queste, il campo-dati pubblico length
dà la lunghezza (dimensione) dell’array: v.length
Una volta creato, un array ha comunque dimensione fissa – non può essere “allargato” a piacere – per tali necessità esiste la classe Vector
nell’esempio precedente vale 3
APPENDICE:
PROGRAMMAZIONE STRUTTURATA
• Scopo: semplificare la lettura dei programmi (e di conseguenza la loro modifica e manutenzione).
• Eliminazione di salti incondizionati (go to) nel flusso di controllo.
• La parte esecutiva di un programma può essere vista come un comando (complesso) ottenuto a partire da istruzioni elementari, utilizzando determinate regole di composizione (strutture di controllo).
PROGRAMMAZIONE STRUTTURATA
Concetti chiave: • concatenazione and composizione BLOCCO
DI CODICE • instruzione condizionale SELEZIONE
– separa il flusso di controllo in base al valore vero/falso di un’espressione booleana
• ripetizione and iterazione CICLO – esegue ripetutamente un’istruzione finchè una
determinata espressione booleana resta vera
STRUTTURE DI CONTROLLO
<block> ::= { [ <statements and definitions> ] { <instructions> } } • la visibilità di una variabile definita
all’interno di un blocco è ristretta al blocco stesso
• non è necessario inserire il punto e virgola alla fine di un blocco (ma serve per terminare istruzioni semplici)
I1
I2
I3
In
BLOCCO
<selection> ::= <choice> | <multiple-choice>
• la seconda non è essenziale e non la vedremo .
ISTRUZIONI CONDIZIONALI
<choice> ::= if (<cond>) <instruction1> [ else <instruction2> ]
condition true false
instruction1 instruction1
La condizione viene valutata all’esecuzione di “if”.
ISTRUZIONI CONDIZIONALI
La parte else è opzionale: se omessa, quando la
condizione è falsa, il flusso di controllo
continua con l’istruzione che segue l’ if
ISTRUZIONI CONDIZIONALI
<choice> ::= if (<cond>) <instruction1> [ else <instruction2> ]
condition true false
instruction2 instruction1
• <istruzione1> e < istruzione2> sono entrambe istruzioni singole
• Se è necessario specificare più di un’istruzione, è necessario utilizzare un blocco
if (n > 0) { /* inizio blocco */ a = b + 5; c = a; } /* fine blocco */ else n = b;
ESEMPIO di ISTRUZIONE if
<iteration> ::= <while> | <for> | <do-while>
• Istruzioni di iterazione:
• hanno un unico punto di ingresso e un unico punto di uscita nel flusso del programma
• quindi, possono essere interpretate come una singola azione in una computazione sequenziale
ISTRUZIONI DI ITERAZIONE
<while> ::= while(<condition>) <instruction>
condition
true
false
instruction
ISTRUZIONE while
• L’istruzione viene ripetuta fino a che la condizione è/rimane
vera • Se la condizione è falsa,
l’istruzione non viene eseguita (nemmeno una volta)
• In generale, non è noto a priori quante volte l’istruzione verrà
ripetuta
Prima o poi, direttamente or indirettamente, l’istruzione dovrà
modificare la condizione: altrimenti, l’iterazione non terminerà mai!
CICLO INFINITO
Quindi, tipicamente l’istruzione è un blocco, all’interno del quale alcune
delle variabili che compaiono nella condizione vengono modificate
<while> ::= while(<condition>) <instruction>
ISTRUZIONE while
condition
true
false
instruction
• È un’evoluzione dell’istruzione while con lo scopo di evitare errori comuni:
• mancanza di una variabile di inizializzazione
• mancanza di una fase di modifica dela variabile all’interno del ciclo (rischio di ciclo infinito)
• In generale, viene utilizzata quando si sa con
certezza quante volte si deve eseguire il ciclo.
ISTRUZIONE for
<for> ::= for( <init-expr>;<cond>;<modif-expr>) <instruction>
condition
true
false
instruction
initialization-expr
modif-expr
struttura while
ISTRUZIONE for
Espressione di inizializzazione: <init-expr>
valutata una sola volta prima dell’inizio dell’iterazione.
Condizione: <cond> , per decidere se proseguire (come nel while).
se mancante, viene assunta come true di default!
Espressione di modifica: <modif-expr> valutata ad ogni iterazione, dopo che l’istruzione è stata eseguita.
condition
true
false
instruction
initialization-expr
modif-expr
<for> ::= for( <init-expr>;<cond>;<modif-expr>) <instruction>
ISTRUZIONE for