capitolo 4

32
CAPITOLO 4 LINGUAGGIO JAVA: COSTRUTTI DI BASE

Upload: grady

Post on 12-Jan-2016

44 views

Category:

Documents


0 download

DESCRIPTION

CAPITOLO 4. LINGUAGGIO JAVA: COSTRUTTI DI BASE. ALFABETO. Java adotta la codifica standard Unicode della società Unicode, Inc. ( ftp://ftp.unicode.org ) definito in: The Unicode Standard, Worldwide Character Encoding , Version 2.0 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: CAPITOLO 4

CAPITOLO 4

LINGUAGGIO JAVA: COSTRUTTI DI BASE

Page 2: CAPITOLO 4

ALFABETO

• Java adotta la codifica standard Unicode della società Unicode, Inc. (ftp://ftp.unicode.org) definito in: The Unicode Standard, Worldwide Character Encoding, Version 2.0

• I programmi Java possono essere scritti con altre codifiche (e.g. la codifica ASCII a 7 o 8 bit), ma devono essere convertiti alla codifica Unicode (a 16 bit) prima di essere utilizzati da parte di compilatori, interpreti, debugger, etc.

• N.B. - Nello standard Unicode, un segmento della codifica è riservato ai caratteri speciali

Page 3: CAPITOLO 4

CODICE SORGENTE

• Consiste di una o più unità di compilazione

• Ogni unità può contenere (oltre ai commenti)– al più una istruzione package

– una o più istruzioni import

– una o più dichiarazioni di classe (class)

– una o più dichiarazioni di interfaccia (interface)

• Per ciascuna unità di compilazione, al più una classe può essere dichiarata public

• Il codice sorgente viene compilato a bytecode (cfr. The Java Virtual Machine Specification), un insieme di istruzioni machine-independent

Page 4: CAPITOLO 4

COMMENTI

• Presenti in tre diversi stili, non hanno alcuna influenza sulla semantica dei programmi– // Primo stile: io sono un commento su di una sola linea

– /* Secondo stile: anch'io sono un commento monolinea */

– /* Secondo stile: io, invece, sono un commento più lungo: non ci sto in una sola linea e quindi ne occupo ben due */

– /** Terzo stile: io sono un commento di tipo speciale, che chiamano "commento di documentazione". */

• Un commento del terzo tipo va collocato solo immediatamente prima di una dichiarazione (di classe, di interfaccia, di costruttore o di membro); viene incluso nella documentazione generabile automaticamente (ex sorgente)

Page 5: CAPITOLO 4

TIPI SEMPLICI

"Non tutti i dati sono oggetti" (impurità di Java)

• boolean - tipo enumerativo (due elementi)

• char - carattere di 16 bit (Unicode 1.1.5)

• byte - intero di 8 bit (complemento a 2)

• short - intero di 16 bit (complemento a 2)

• int - intero di 32 bit (complemento a 2)

• long - intero di 64 bit (complemento a 2)

• float - floating-point di 32 bit (IEEE 754)

• double - floating-point di 64 bit (IEEE 754)

Tutti i tipi semplici (o di base) sono predefiniti

Page 6: CAPITOLO 4

TIPI COMPOSTI

• Equivalenti alle variabili strutturate PASCAL, nella loro versione dinamica (operatore new)

• I dati composti sono mediati, i.e. manipolati per mezzo di puntatori non visibili all'utente (i dati semplici sono immediati, i.e. manipolati direttamente)

• Tre categorie di tipi composti– Matrici - versione dinamica degli array PASCAL

– Classi - versione "attiva" dei record PASCAL

– Interfacce - simili alle dichiarazioni forward in PASCAL

• Di questi, solo i tipi matrice sono predefiniti: le librerie di classi e di interfacce non lo sono

Page 7: CAPITOLO 4

LETTERALI (1)

• Rappresentazione "esterna" di dati e oggetti

• Alcuni tipi semplici ammettono letterali– boolean - true, false

– char - 'a', '\u03ff', '\037', '\x7f'

- '\', '\n', '\t', '\b', '\r', '\f', '\\', '\'', '\"'

– int - 127, 0177, 0x7F, 0X7F, 0x7f, 0X7f

– long - 127L, 127l, 2147483648

– float - 3.14, 3.1E12, 3.1e-12, .1e12, 2e-12

– double - 3.14D, 3.14d, 3.1e-12D, .1e12d, 2e-12D

• Uno solo dei tipi composti ammette letterali– String - "", "Da\ncapo", "Io non sono Luigi Stringa"

• Per gli altri esiste il letterale generico null

Page 8: CAPITOLO 4

LETTERALI (2)

• Letterali distinti possono rappresentare lo stesso valore– int - 127, 0177, 0x7F

• I numeri negativi, di qualunque tipo siano (salvo gli esponenti), non sono esprimibili mediante letterali

• Le routine di stampa sono in grado di stampare qualunque dato di tipo semplice

• Il formato di stampa è coerente con quello dei letterali (se esiste); nel caso di più formati possibili, ne viene scelto uno come standard

Page 9: CAPITOLO 4

PAROLE CHIAVE (RISERVATE)

• Parole chiave: abstract, boolean, break, byte, case, catch, char, class, const (*), continue, default, do, double, else, extends, final, finally, float, for, goto (*), if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, super, switch, synchronized, this, throw, transient (*), try, void, volatile, while

(*) Inutilizzata nella specifica attuale di Java

Page 10: CAPITOLO 4

IDENTIFICATORI

• Debbono iniziare con una lettera (v. sotto) o con uno dei due simboli '_' e '$', e possono contenere qualunque carattere non speciale della codifica Unicode; non hanno (in pratica) limiti di lunghezza

• Ai fini di Java, sono lettere– tutti i caratteri compresi tra 'A' e 'Z' e tra 'a' e 'z'

– le non-cifre di codice Unicode superiore a 00C0 (hex)

• Esempi: identifier, user_name, User_name, _user_name, $user_name, user$name1

• Se attributi di classi, sono inizializzati a false (i boolean), 0 (i tipi numerici) o null (il resto)

Page 11: CAPITOLO 4

MATRICI

• Vettori monodimensionali di dati, semplici o composti, di tipo omogeneo– Semplici - char a[]; char[] b; char array[];

– Composti (oggetti) - String args[]; String[] other_args;

– Composti (matrici) - char chess[][]; char[][] checkers; Voxel human_body[][][];

• Indicizzati con int (indice primo elemento = 0), con controllo di validità degli indici a run-time

• Vanno create e dimensionate esplicitamente, anche contestualmente alla dichiarazione (la quale di per sé non alloca nulla, ma si limita a definire il tipo di un nome, inizializzato a null)

Page 12: CAPITOLO 4

MATRICI: CREAZIONE INIZIALIZZAZIONE

• Dichiarazione e successiva creazione int array[][]; /* qui array == null */

array = new int[10][3];

• Dichiarazione e contestuale creazione int array[][] = new int[10][3];

• Dichiarazione e parziale creazione int array[][] = new int[10][];

• Dichiarazione, creazione e inizializzazione– String names[] = {"Tic","Tac"} /* equivalente a ... */

– String names[] = new String[2];

names[0] = "Tic"; names[1] = "Tac";

Page 13: CAPITOLO 4

ERRORI CON LE MATRICI

• Tentare di dimensionare una matrice nella (e non contestualmente alla) sua dichiarazione

int list [50];

• Tentare di inizializzare una matrice prima di averla creata

int list[];

for (int i=0 ; i<9 ; i++)

{ list[i] = i; }

• Prima della sua creazione (operatore new) la matrice non esiste: la dichiarazione ha l'unico scopo di specificare il tipo della variabile (che comprende solo il numero delle dimensioni)

Page 14: CAPITOLO 4

MATRICI COME CLASSI

• Dalla classe Object, la capostipite di tutte le classi, deriva la classe Array, dotata di un metodo length ereditato dalle sue sottoclassi

int a[][] = new int[10][3];

a.length; /* 10 */

a[0].length; /* 3 */

• Per ogni tipo (semplice o composto) esiste implicitamente una sottoclasse di Array che comprende tutte le matrici di oggetti di quel tipo (N.B. da Array non si possono derivare sottoclassi esplicitamente)

• Se B è sottoclasse di A, allora B[] lo è di A[]

Page 15: CAPITOLO 4

CLASSI, ATTRIBUTI E METODI

• Esempio di classepublic class MyClass {

int i; /* attributo */

public MyClass () { /* metodo costruttore: ha lo

i = 10; stesso nome della classe */

}

public void Add_to_i (int j) { /* altro metodo */

i = i+j;

}

}

• Ricordiamo che Java non adotta il modello a oggetti puro: "non tutti i dati sono oggetti"

Page 16: CAPITOLO 4

FUNZIONI E POLIMORFISMO: OVERLOADING DI METODI

• Variante dell'esempio precedentepublic class MyNewClass {

int i; /* attributo */

public MyNewClass () { /* metodo costruttore: ha lo

i = 10; stesso nome della classe */

}

public MyNewClass (int j) { /* altro metodo costruttore

i = j; diverso dal precedente */

}

.....

}

• Metodi omonimi devono essere distinguibili per la quantità e/o per il tipo degli argomenti

Page 17: CAPITOLO 4

ATTRIBUTO this

• Implicitamente presente in ogni oggetto, è sempre legato all'oggetto medesimo

public class MyNewClass {

int i; /* attributo */

public MyNewClass () {

i = 10;

}

public MyNewClass (int i) { /* parametro */

this.i = i; /* disambiguazione */

}

.....

}

• Risolve omonimie e.g. tra attributi e parametri

Page 18: CAPITOLO 4

CREAZIONE DI OGGETTI

• Creazione e uso di un oggetto con MyClassMyClass mc; /* dichiarazione, non creazione */

mc = new MyClass(); /* creazione: l'attributo i vale 10 */

mc.i++; /* ora i vale 11 */

mc.Add_to_i(10); /* e ora i vale 21 */

• Creazione di un oggetto con MyNewClassMyNewClass mc0, mc1; /* dichiarazione, non creazione */

mc0 = new MyNewClass(); /* creazione: l'attributo i vale 10 */

mc0.i++; /* ora i vale 11 */

mc1= new MyNewClass(20); /* creazione: l'attributo i vale 20 */

mc1.i++; /* ora i vale 21 */

Page 19: CAPITOLO 4

DISTRUZIONE DI OGGETTI

• Java non supporta "distruttori" espliciti: gli oggetti non si distruggono, si "riciclano"

• Un oggetto privo di puntatori incidenti non è più accessibile alle applicazioni e la memoria che esso occupa può essere "riciclata"

String s; /* dichiarazione, non creazione */

s = new String ("abc"); /* creazione: s punta a "abc" */

s = "def"; /* "abc" non è più puntata da s */

• Il "riciclatore" (garbage collector, o GC) opera in un thread indipendente (i.e. "in parallelo" con altri thread, sia di utente che di sistema)

Page 20: CAPITOLO 4

FINALIZZATORI DI OGGETTI

• Un oggetto "riciclabile" (i.e. privo di puntatori incidenti) potrebbe trovarsi in uno stato poco "pulito" (e.g. in passato potrebbe aver aperto dei file che non sono stati ancora chiusi)

• Prima di procedere alla fase cruenta, il GC invoca il metodo finalize di ciascun oggetto "riciclabile", definibile da utente

protected void finalize () /* per protected vedi oltre */

{ close (); } /*chiudi tutti i file aperti */

• Il metodo finalize esiste sempre: se non è stato ridefinito viene ereditato da Object

Page 21: CAPITOLO 4

CLASSI: SINTASSI

[Doc comment][Modifiers] class ClassName

[extends SuperClassName]

[implements InterfaceName [, InterfaceName]]

{ClassBody}

Doc comment - commento "di documentazione"

Modifiers - uno o più dei qualificatori abstract, final, public/protected/private, native, synchronized, transient, volatile

extends - la classe è sottoclasse di un'altra (e di una sola: ereditarietà singola)

implements - la classe realizza una o più interfacce

(può "simulare" ereditarietà multipla)

ClassBody - gli attributi e i metodi della classe

Page 22: CAPITOLO 4

CLASSI E SOTTOCLASSI

• Le zebre come particolari tipi di cavallo...

public class Horse { int Head, Tail, Legs, Body;

public Horse () { Head = 1; Tail = 1; Legs = 4; Body = 1; }

public void AddLegs (int Legs) { this.Legs += Legs;}

}

public class Zebra extends Horse {

int Stripes;

public Zebra (int Stripes) { this.Stripes = Stripes; }

public void AddLegs (int Legs) /* ridefinizione */

{ this.Legs += Legs + Stripes; }

}

Page 23: CAPITOLO 4

SOTTOCLASSI E super

• Manipoliamo le zampe di una nuova zebraZebra mz;

mz = new Zebra(1000000000); /* ha 4 zampe */

mz.AddLegs(4); /* ora ne ha 1000000008 */

• Il vecchio metodo AddLegs è ancora usabilemz.super.AddLegs(4); /* ora ne ha 1000000012 */

• L'attributo super, implicitamente presente in ogni oggetto, permette di "ricuperare" un attributo/metodo da una (sopra)classe dopo che è stato ridefinito in una sua (sotto)classe

Page 24: CAPITOLO 4

SOTTOCLASSI E CASTING

• Proseguendo con l'esempio precedenteHorse mh = (Horse)mz; /* ora è vista come cavallo */

mh.AddLegs(4); /* ora ha 1000000016 zampe */

(Zebra)mh.AddLegs(4); /* ora ne ha 2000000020 */

• Il cast da una classe a una sottoclasse (anche non diretta) è possibile se l'oggetto è davvero un esemplare della sottoclasse (il controllo è fatto a run-time); il viceversa è sempre OK

• Il cast per linea di discendenza non diretta è un errore (il controllo è fatto a compile-time)

• Il cast non altera gli oggetti: influisce solo sul modo di "osservare" un puntatore all'oggetto

Page 25: CAPITOLO 4

METODI: SINTASSI

[Doc comment][Modifiers] ReturnType MethodName

(ParameterList)

{MethodBody}

Modifiers - uno o più dei qualificatori abstract,

final, public/protected/private, native, synchronized, transient, volatile

ReturnType - va omesso nei costruttori, ma va indicato (eventualmente void) negli altri casi; deve essere identico al tipo ritornato da metodi sovrascritti

ParameterList - deve essere coerente con quella dei metodi sovrascritti

MethodBody - le variabili locali devono essere inizializzate prima di essere usate

Page 26: CAPITOLO 4

ACCESSI E CONDIVISIONE

• Quattro tipi di diritti d'accesso– public void AnyOneCanAccess () { ... }

– protected void OnlySubclassesCanAccess () { ... }

– private void NoOneElseCanAccess () { ... }

– void OnlyFromWithinMyPackage () { ... }

L'ultimo tipo si chiama "friendly"

• Attributi statici: condivisi da tutte le istanze; metodi statici: operano solo su dati statici

class NewDocument extends Document {

static int Version = 10; int Chapters;

static void NewVersion () { Version++; } /* OK */

static void AddChapter () { Chapters++; } } /* KO */

Page 27: CAPITOLO 4

TIPI DI CLASSE

• Quattro tipi di classi– abstract: tra i vari metodi, deve contenerne almeno uno abstract,

ma non può contenere metodi private o static; deve dare origine a sottoclassi; non può essere istanziata

– final: termina una catena di classi-sottoclassi, non può dare origine a ulteriori sottoclassi

– public: può essere usata senza formalità nel package che ne contiene la dichiarazione; disponibile anche in altri package, purché vi venga "importata"

– synchronized: tutti i metodi interni sono synchronyzed

• Classi astrattepublic abstract class Graphics { /* generica */

public abstract void DrawLine(int x1,y1,x2,y2); }

public class VGA extends Graphics { /*specifica */

public void DrawLine(int x1,y1,x2,y2) { <codice per VGA> }}

Page 28: CAPITOLO 4

INTERFACCE

• Alternativa alle classi astratte: non richiede la derivazione esplicita di sottoclassi

public interface AudioClip {

void play (); /* avvia i'esecuzione */

void loop (); /* esegui ciclicamente una audio clip */

void stop (); } /* interrompi l'esecuzione */

class MyAudio implements AudioClip {

void play () { <codice che implementa play> }

void loop () { <codice che implementa loop> }

void stop () { <codice che implementa stop> } }

class YourAudio implements AudioClip { <codice> }

• I metodi possono essere public o abstract, gli attributi public, static o final

Page 29: CAPITOLO 4

OPERATORI E PRECEDENZA

• Operatori (ordine di precedenza decrescente):. [] ()

++ --

! ~ instanceof

* / %

+ - /* anche: String name = "Luigi" + "Stringa" */

<< >> >>>

< > <= >= == != /* ritornano un booleano */

& ^ |

&& ||

? ... : ...

= += -= *= /= &= |= ^= %= <<= >>= >>>=

Page 30: CAPITOLO 4

ISTRUZIONI CONDIZIONALI

• If– if (boolean) { statements; } else { statements; }

• Case– switch (expr) { case tag1:

statements;

break;

.....

case tagn:

statements;

break;

default:

statements;

break;

}

Page 31: CAPITOLO 4

ISTRUZIONI ITERATIVE

• For– for (init expr1 ; test expr2 ; incr expr3) { statements; }

• While– while (boolean) { statements; }

• Do– do { statements; } while (boolean)

• Controllo di flusso– break [label]

– continue [label]

– return expr;

– label: statement

Page 32: CAPITOLO 4

FOR, SWITCH, CONTINUE E BREAK: PRECISAZIONI

label: for (int i =0 , int j=0 ; i<10 && j<20; i++ , j++) { /* exp */

for (int z=0 ; z<100 ; z++) { /* scope è solo il for */

switch (expr) {

case tag:

statements;

break; /* prosegue con penultima riga */

.....

default:

statements;

break label; } /* prosegue da label */

if (z==15) continue; /* prosegue il for z */

if (z==i+j) continue label; /* prosegue da label */

}

}