Java 01

download Java 01

If you can't read please download the document

Transcript of Java 01

Diapositiva 1

Java

Programmazione ad oggetti

Davide [email protected]

Di cosa parleremo

Differenze tra programmazione strutturata e programmazione ad oggetti

Concetti fondamentali della OOP (Object Oriented Programming)

Classi ed istanze

La OOP ed i costrutti Java

Caratteristiche della Programmazione strutturata /1

La Programmazione strutturata si basa su alcuni basilari principi

Esistono le variabili locali e globali (strutture dati)

Esiste il concetto di blocco di istruzioni (funzione e/o procedura) che esegue un compito preciso utilizzando le variabili locali e/o globali

le variabili contengono i dati su cui il programma agisce

Le funzioni rappresentano la logica (algoritmo) da applicare sui dati per ottenere un risultato

I dati e le funzioni sono disaccoppiati nel senso che una funzione non possiede l'accesso esclusivo ad un dato

Caratteristiche della Programmazione strutturata /2

Il celebre libro di Niklaus Wirth palesa come nella programmazione strutturata la somma di Algoritmi e Strutture Dati produca i programmi

Nella OOP la separazione tra Algoritmi e Strutture Dati sparisce (o quasi).

Questa una delle pi significative differenze tra i due paradigmi di programmazione

Concetti generali della OOP

Cosa un oggetto

Incapsulamento (information hiding)

Ereditariet

Polimorfismo

Cosa un oggetto

Un oggetto una entit software dotata di

Stato

Comportamento

Pensiamo all'entit software Animale, un animale pu mangiare e muoversi, ha un nome e pu essere affamato

In genere

i verbi indicano comportamento (muoversi, mangiare)

i sostantivi (nomi) indicano lo stato (nome,et)

questa regola non e' perfetta ma abbastanza precisa

Definiamo una entit
Oggetto Animale

Stato

Nome

Fame

Colore

Comportamento

Mangiare

Muoversi

Parlare (nel senso di emettere suoni)

Fido e Polly
Stato e Comportamento

Animale

fido = new Cane(Fido);

fido.muovi();fido.parla(); // baubau

// Verifico lo statofido.getNome(); // Fidofido.getFame(); // pocafido.muovi();fido.getFame(); // molta

polly = new Pappagallo(Polly);

polly.muovi(); // si muove sul trespolo non vola!polly.parla(); // mi chiamo pooolly

// Verifico lo statopolly.getNome(); // Polly

Come sono legati stato e comportamento?

Animale

fido.muovi();

// Verifico lo statofido.getFame(); // pocapolly.muovi();

// Verifico lo statopolly.getFame();L'algoritmo presente in muovi agisce sullo stato fame cambiando i valori di alcune variabili (strutture dati) contenute negli oggetti

Non sappiamo nulla su come funziona l'algoritmo che probabilmente diverso per ogni animale

Riepilogando si pu dire che nella OOP in generale

Lo stato cambia impostando i valori di variabili (es. fame = 100)

Il comportamento lavora sulle variabili (es. incrementa il valore)

Incapsulamento /1

La fame di Fido e Polly aumenta pi velocemente se si muovono

Quando la fame al massimo supponiamo che si rifiutino di muoversi

Richiamando il metodo mangia() Fido riprender a camminare.

Posso leggere lo stato fame con getFame() e cambiarlo con mangia(), non posso dare dei valori non previsti allo stato:

questo

Incapsulamento o information hiding

Incapsulamento /2

L'information hiding

nasconde i dettagli implementativi

impedisce di falsare lo stato dell'oggetto con dei valori non ammessi.
I valori delle variabili possono essere cambiati solo dall'oggetto e non dall'esterno

Ereditariet /1

Sia Fido che Polly sono animali

Essi hanno in comune molte caratteristiche

Nome (stato)

Si muovono (comportamento)

Queste propriet sono dell'entit Animale e le entit Cane e Pappagallo le ereditano

Ereditariet /2

Ereditariet /3

L'ereditariet pu essere modellata secondo diversi livelli di precisione

Ereditariet /4

Ereditariet significa avere un oggetto base con un insieme di stati e comportamenti presenti anche in oggetti derivati*

Si parla di gerarchia di oggetti quando un oggetto possiede dei discendenti che a loro volta ne hanno altri (si pensi all'albero genealogico)

* ereditare e derivare sono sinonimi in OOP

Ereditariet /5

Se Fido e Polly sono uguali all'oggetto Animale che bisogno c' di creare due nuovi oggetti Cane e Pappagallo?

Si sarebbe potuto scrivere qualcosa di pi semplice

fido = new Animale("Fido") invece di fido = new Cane("Fido")

polly = new Animale("Polly") invece di polly = new Pappagallo("Polly")Gli oggetti hanno caratteristiche comuni ma non sono uguali!!Fido corre pi velocemente di PollyPolly pu volare ed anche il suono emesso diversoIl comportamento cambia e questo si chiamaPolimorfismo

Polimorfismo /1

Preso da Wikipedia, significa
assumere significati specifici in diversi contesti

Nel mondo OOP significa
la capacita' di ridefinire il comportamento di un oggetto

Sia Fido che Polly hanno un metodo parla ma il risultato un p diverso...

Il metodo parla ereditato dall'entit Animale

Polimorfismo /2

Nel caso di Fido e Polly significa che il comportamento applicato, ad esempio, nel metodo muovi cambia negli oggetti Cane e Pappagallo

Comportamento = Algoritmo; quindi il metodo Cane.muovi() e Pappagallo.muovi() contengono codice diverso

Relazioni tra classi

Le classi possono essere in relazione tra loro come

Associazione (uso di oggetti)

Aggregazione (contenimento di oggetti)

Specializzazione (ereditariet)

Relazioni / Associazione

Una classe si dice in associazione con un'altra quando esiste un legame debole o nullo

Supponiamo che esista una classe Collare, Fido potrebbe avere un attributo (field) di questo tipo.

Fido per pu tranquillamente esistere senza collare (legame debole) quindi l'attributo collare della classe pu essere vuoto

Relazioni / Aggregazione

Una classe si dice in aggregazione con un'altra quando esiste un legame forte

Supponiamo che Fido abbia l'attributo et, questo attributo deve esistere ed avere un valore valido (legame forte)

La differenza tra Associazione e Aggregazione molto sottile spesso ci si limita a dire che una classe ha un attributo di un'altra e questo attributo pu essere null oppure valorizzato

Relazioni / Specializzazione

Una classe si dice specializzazione di un'altra quando deriva da essa

Cane o Pappagallo sono specializzazioni di Animale

Animale detta classe base

La fattoria degli animali in Java

Tutti i concetti OOP trovano diretto riscontro nella sintassi del linguaggio Java

Incapsulamento (Information hiding)

Ereditariet

Polimorfismo

Prima di vedere questi aspetti prendiamo confidenza con la sintassi specifica di Java

Definire un oggetto in Java

Java utilizza la parola riservata class per definire un oggetto

class un contenitore di

variabili (che in java di chiamano field)

funzioni (che in java si chiamano metodi)

nome una variabile

getNome e setNome sono due metodi

class Animale { String nome;

String getNome() { return nome; }

void setNome(String nuovoNome){ nome = nuovoNome; }

}

Metodi con nomi "speciali"

class Animale { String nome;

String getNome() { return nome; }

void setNome(String nuovoNome){ nome = nuovoNome; }

}Java usa una convenzione per i nomi dei metodi.
Essendo una convenzione non obbligatoria ma caldamente consigliata.

Tutti i metodi che restituiscono il valore di un field hanno il prefisso get

Tutti i metodi che impostano il valore di un field hanno il prefisso set

Getter e setter

I getter e setter sono normali metodi, e' solo una convenzione "umana" quella

di avere i getter che non prendono argomenti

di avere i setter che prendono un solo argomento

Nulla vieta di avere un setter che non riceve nessun argomento oppure un getter che prende uno o piu' argomenti

Un oggetto contenente getters e setters viene chiamato Java beanSi consiglia l'attenta lettura della naming conventionhttp://java.sun.com/docs/codeconv/html/CodeConventions.doc8.html

Istanze di oggetti

Una volta definito il contenuto di una classe con field e metodi per utilizzarlo bisogna istanziarlo

Questo viene fatto con l'operatore new di Java che alloca in memoria un nuovo oggetto del tipo richiesto

Animale fido = new Animale();

Ne consegue che

Una classe rappresenta la definizione di un oggetto

Una istanza la sua struttura in memoria sulla quale possibile cambiare il valore dei field

Istanze e costruttori

Quando si crea un nuovo oggetto, ovvero una istanza, si richiama uno speciale metodo chiamato costruttore

Il costruttore ha lo stesso nome della classe e non ritorna niente

Possono esserci pi costruttori per una classe a patto che prendano parametri diversi

Se non viene dichiarato nessun costruttore Java ne crea uno automaticamente che azzera tutti i field e non riceve argomenti

Si chiama costruttore di default

Esempi di costruttori

public class Animale {}public class Animale { public Animale() { }}

Le classi sono identiche, quella a destra viene generata in fase di compilazione da Java.Attenzione! Non viene modificato il sorgente ma la classe compilata che in assenza di un costruttore viene creata con quello di defaultpublic class Animale { public Animale() { }

public Animale(String nome) { } public Animale(String nome) { } }public class Animale { public Animale() { }

public Animale(String nome) { } public Animale(String nome, String razza) { } }

Information Hiding e violazione

Il contenuto della variabile 'nome' pu essere cambiato facilmente senza nessun controllo

public class ProvaAnimaleSenzaInformationHiding { public static void main(String[] args) { Animale fido = new Animale();

fido.nome = "aaa"; }}Questa una violazione dell'IH

Non abbiamo adeguatamente nascosto la variabile da modifiche arbitrarie

Java ed i livelli di
Information Hiding (IH)

In Java possibile scegliere chi deve vedere cosa.

I field ed i metodi possono avere differenti livelli di IH

Esistono tre livelli di IH

public tutti possono vedere e/o modificare il field e/o il metodo

protected solo le classi derivare possono vedere e/o modificare il field e/o il metodo

private solo la classe contenente il field e/o il metodo pu accederci

Esiste un quarto livello, package, ma non si utile ai nostri scopi

Diminuiamo la visibilit

class Animale { String nome;

String getNome() { return nome; }

void setNome(String nuovoNome){ nome = nuovoNome; }

}class Animale { private String nome;

String getNome() { return nome; }

void setNome(String nuovoNome){ nome = nuovoNome; }

}Cosa cambia

Con questa piccola modifica la classe xxx non compila pi.Abbiamo impedito modifiche dirette al field 'nome'Anche protected avrebbe nascosto la visibilit.Domanda: Cosa avrebbe fatto invece public?Domanda: Come faccio a cambiare il nome adesso?

Best practices per
l'information hiding

E' pratica diffusa e altamente consigliabile

definire i field sempre private

definire i metodi che devono restituire o impostare lo stato di un field public

definire i metodi che non aggiungono significato all'oggetto come protected o private (ad esempio un metodo che controlla la validit del field 'nome')

Overloading

Abbiamo visto che una classe pu avere pi di un costruttore, purch gli argomenti differiscano per numero oppure per tipo

Questa caratteristica si chiama Overloading

Tutti i metodi, non soltanto i costruttori, possono fare overloading

public class Animale { public void muovi() {

}

public void muovi(double centimetri) {

}}

Esercizi cosa sapere

Cosa sapere per svolgere gli esercizi

Per stampare a video una stringa
System.out.println("hello");

Se ad una stringa non viene assegnato nessun valore, viene impostata a null (null e' una parola riservata Java)

Per avviare una classe inserire il metodo main

public static void main(String[] args) {

}

Esempio

Scrivere la classe Animale contenente il metodo getNome()

Scrivere la classe TestAnimale con il metodo main che stampa il nome di una istanza Animale

public class Animale {

public String getNome() { return "Polly"; }}

public class TestAnimale {

public static void main(String[] args) {Animale animale = new Animale();

System.out.println(animale.getNome());}

}

Esercizio 1

Definire una classe Gatto il cui costruttore prende un nome

Definire una classe Canarino il cui costruttore prende un nome

Definire una classe Fattoria che memorizza il gatto ed il canarino

ha un metodo stampaNomiAnimali che stampa tutti I nomi degli abitanti della fattoria

Definire una classe TestFattoria (con il main) che

Istanzia un gatto di nome "Silvestro" ed un un canarino di nome "Titti"

istanzia una fattoria

Inserisce il gatto ed il canarino nella fattoria

Richiama il metodo stampaNomiAnimali

Usare getters, setters e l'information hiding

Classi Gatto e Canarino

public class Gatto { private String nome;

public Gatto(String nome) { this.nome = nome; }

public String getNome() { return nome; }}

public class Canarino { private String nome; public Canarino(String nome) { this.nome = nome; }

public String getNome() { return nome; }}

Classe Fattoria

public class Fattoria { private Gatto gatto; private Canarino canarino;

public Gatto getGatto() { return gatto; }

public void setGatto(Gatto gatto) { this.gatto = gatto; }

public Canarino getCanarino() { return canarino; }

public void setCanarino(Canarino canarino) { this.canarino = canarino; }

public void stampaNomiAnimali() { System.out.println(gatto.getNome()); System.out.println(canarino.getNome());

}}

Classe testFattoria

public class TestFattoria { public static void main(String[] args) { Gatto gatto = new Gatto("Silvestro"); Canarino canarino = new Canarino("Titti"); Fattoria fattoria = new Fattoria(); fattoria.setGatto(gatto); fattoria.setCanarino(canarino);

fattoria.stampaNomiAnimali(); }}

21/06/08