Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoSavio Mari Modificato 11 anni fa
1
Fisica Computazionale I - 41 APPROFONDIMENTI Dobbiamo approfondire a questo punto le nostre conoscenze delle regole di Java, definendo in modo rigoroso anche una serie di modificatori che abbiamo finora utilizzato in modo inconsapevole. E' importante che tutti i principali aspetti del linguaggio siano definiti in modo formale una volta per tutte.
2
Fisica Computazionale I - 42 IL MODIFICATORE 'STATIC' Questo modificatore indica che un campo assume lo stesso valore per tutte le istanze di una classe. Riprendiamo l'esempio Libro.java, e modifichiamolo, aggiungendo una nuova String
3
Fisica Computazionale I - 43 //================================================== public class Libro{ static String CATEGORIA = "carta"; String autore; String titolo; double prezzo; public Libro(){ } public Libro(String a, String t, double p) { autore = a; titolo = t; prezzo = p; } public String getAutore(){return autore;} public String getTitolo(){return titolo;} public static String getCategoria(){return CATEGORIA;} public double getPrezzo(){return prezzo;} public void setAutore(String a){ autore = a;} public void setTitolo(String a){ titolo = a;} public void setPrezzo(double b){ prezzo = b;} public static void setCategoria(String b){ CATEGORIA = b} } //====================================================
4
Fisica Computazionale I - 44 Il campo CATEGORIA e' inizializzato al valore "carta". Tutte le istanze del Libro avranno pertanto quel valore. Se, ad un certo istante, nel nostro programma che utilizza istanze di Libro, modifichiamo la categoria, con l'istruzione Libro.setCategoria("Nuova categoria"); tutte le istanze presenti in memoria verranno modificate, e le istanze create successivamente nasceranno con il valore di CATEGORIA modificato. Si noti che il metodo static, proprio per il suo significato, si applica alla classe e non alle istanze. Non c'e' bisogno infatti di aver creato nessuna istanza di Libro per modificare un campo static.
5
Fisica Computazionale I - 45 Naturalmente modificare un valore di una variabile static e' una operazione da fare con assoluta consapevolezza di cio' che essa significa. Ci sono comunque dei casi in cui variabili static vengono usate per immagazzinare valori assolutamente costanti ed immutabili (ad esempio, il valore numerico di pigreco). In quel caso puo' essere conveniente usare il modificatore final final static double PIGRECO = 3.14159; la dichiarazione final implica che il valore non potra' essere modificato da nessuno.
6
Fisica Computazionale I - 46 METODI SOVRACCARICHI (OVERLOADING) Una classe puo' contenere piu' definizioni dello stesso metodo, purche' essi siano distinguibili per numero e/o tipo degli argomenti. Prendiamo di nuovo il nostro oggetto Libro; potremmo aggiungere nel codice il metodo: public void setPrezzo(String b) { prezzo = Double.parseDouble(b); } Libro conteneva gia' il metodo setPrezzo(double b); con questa aggiunta abbiamo due possibili usi del metodo, uno con argomento double e l'altro con argomento String.
7
Fisica Computazionale I - 47 Possiamo ora capire come, per esempio, il metodo System.out.println(...) accetti come argomento sia String, che tipi primitivi, int, double, ecc. Cio' e' ottenuto proprio attraverso multiple definizioni del metodo. Come abbiamo detto le diverse definizioni del metodo devono essere distinguibili. Il buon senso ci aiuta a capire che la distinguibilita' e' data proprio attraverso il numero e il tipo di argomenti: quando il compilatore Java trova, nella nostra applicazione, la chiamata ad un metodo sovraccarico, e' in grado di selezionare la definizione appropriata.
8
Fisica Computazionale I - 48 EREDITARIETA' Una classe Java puo' utilizzare le proprieta' di un'altra classe, cioe' i campi ed i metodi, come se fossero propri, attraverso un meccanismo che prende il nome di ereditarieta' (inheritance). Possiamo comprendere meglio questo meccanismo attraverso un esempio. Definiamo la classe Dizionario con il seguente codice: public class Dizionario extends Libro{ String lingua; public void setLingua(String l){ lingua = l; } public String getLingua(){ return lingua; }
9
Fisica Computazionale I - 49 Abbiamo costruito una nuova classe, Dizionario, e, attraverso la clausola 'extends Libro', dichiariamo che questa classe eredita tutte le proprieta' della classe Libro, che avevamo definito in precedenza. In piu', aggiungiamo un campo, la lingua. In sostanza il dizionario appartiene alla categoria generale dei libri, con una proprieta' in piu'. Si comprende come questa capacita' degli oggetti di mutuare caratteristiche e proprieta' di altri oggetti aumenta enormemente la potenza del linguaggio. Ci consente di organizzare in modo molto semplice ed elegante le nostre applicazioni, utilizzando oggetti semplici per costruirne di piu' complessi, senza bisogno di ridefinire tutte le proprieta' rilevanti.
10
Fisica Computazionale I - 410 Le classi Java sono quindi organizzate in una gerarchia padre-figlio, ovvero superclasse-sottoclasse. Ogni classe puo' avere al massimo una superclasse, cioe' puo' ereditare solo da un'altra classe; ogni classe viceversa puo' avere molte sottoclassi, cioe' puo' dare in eredita' le proprie caratteristiche a piu' 'figli'. L'ereditarieta' si trasmette: una classe eredita tutte le proprieta' della propria superclasse, incluse quelle che essa, a sua volta, ha ereditato. Al vertice della gerarchia delle classi Java siede la classe Object: tutte le classi Java ereditano quindi le sue proprieta'. Ovviamente Object e' l'unica classe a non avere superclasse.
11
Fisica Computazionale I - 411 Una sottoclasse puo' ereditare tutti i metodi e le variabili della superclasse, come se fossero propri e, naturalmente aggiungere proprie variabili e metodi. Ma una sottoclasse puo' anche sostituire metodi e variabili ereditate cambiandone il significato attraverso nuove definizioni (shadowing). Questa possibilita' e' molto piu' ampia del sovraccaricamento visto in precedenza: possiamo proprio sostituire il metodo, o il campo, con una nuova definizione. Nella terminologia Java questo e' definito come method overriding; in sostanza porta alla possibilita' di modificare il comportamento di un oggetto, attraverso appunto la creazione di una sottoclasse con comportamenti diversi, dando luogo ad un polimorfismo delle sottoclassi.
12
Fisica Computazionale I - 412 Il processo di sostituzione di un metodo, nell'ambito di una sottoclasse, non impedisce comunque di fare riferimento al metodo originario della superclasse, attraverso lo specificatore super. Per esempio: public class Articolo{........ public void descrizione(){........ }........ }
13
Fisica Computazionale I - 413 public class Bullone extends Articolo{........ public void descrizione(){........ super.descrizione() }........ } La classe Articolo ha, tra gli altri un metodo descrizione; la classe Bullone sostituisce il metodo descrizione, aggiungendo alcune caratteristiche, ma riprendendo poi il resto del codice dal metodo omologo della superclasse.
14
Fisica Computazionale I - 414 L'estendibilita' di una classe puo' essere limitata attraverso il modificatore final. Un campo, o un metodo, dichiarato final, non puo' essere sostituito; se tutta la classe e' dichiarata final (per esempio public final class Yxxxx) essa non puo' essere estesa. Molte classi fondamentali di Java sono final: per esempio le classi Integer, String, Double,.... Una sottoclasse implementa in genere uno o piu' costruttori che la definiscono. Ma puo' anche utilizzare in tutto o in parte, i costruttori della propria superclasse, attraverso lo statement super.
15
Fisica Computazionale I - 415 class Persona{ Persona(String nome){........ }........ } class Contribuente extends Persona{ Persona(String nome, String codiceFiscale){ super(nome);........ }........ }
16
Fisica Computazionale I - 416 In questo esempio il costruttore del Contribuente sfrutta la parte di codice che gestisce il nome, ricavandolo dalla superclasse. Per poter far questo correttamente, e' tassativo che l'istruzione super(..) sia la prima istruzione del nuovo costruttore.
17
Fisica Computazionale I - 417 CASTING Il casting ordina esplicitamente al compilatore di cambiare il tipo apparente di un oggetto. In Java la liceita' dell'operazione di casting e' verificata sia in fase di compilazione che in fase di esecuzione. Un tentativo di casting di un oggetto su un tipo non compatibile genera, al momento dell'esecuzione, una eccezione ClassCastException. Il casting e' utilizzato per restringere il tipo, rendendolo piu' specifico. Questo e' generalmente usato per estrarre un oggetto specifico da una collezione di oggetti generici.
18
Fisica Computazionale I - 418 Possiamo capire meglio questo discorso con un esempio, in cui utilizzeremo un nuovo oggetto Java, il Vector. Vector consente di costruire collezioni ordinate di oggetti (anche eterogenei), e possiede vari metodi per manipolarle. Sempre utilizzando il nostro oggetto Libro, possiamo ora scrivere questo esempio: Libro libro1 = new Libro("Mario Rossi","Manuale Java",30.0); Libro libro2 = new Libro("Luigi Bianchi","Manuale HTML",30.0); Libro libro1 = new Libro("Andrea Verdi","Manuale C++",30.0); Vector v = new Vector(); v.addElement(libro1); v.addElement(libro2); v.addElement(libro3);
19
Fisica Computazionale I - 419 abbiamo costruito una istanza v della classe Vector e vi abbiamo collezionato 3 libri, con il metodo addElement(). Piu' tardi avremo bisogno di estrarre dal Vector i suoi elementi, utilizzando il metodo elementAt(int j), che ci restituisce l'oggetto nella posizione j-esima. Ora il metodo elementAt restituisce un Object generico, mentre noi abbiamo bisogno di specificare che l'oggetto e' un libro; quindi scriveremo: Libro ll1; ll1 = (Libro)v.elementAt(0); recuperando il libro posto nella prima posizione del vettore la scrittura (Libro) che precede la chiamata al metodo svolge appunto questa funzione di casting, cioe' 'forgiatura' dell'oggetto generico ridandogli la sua corretta natura di libro.
20
Fisica Computazionale I - 420 E' ovvio che e' nostra responsabilita' effettuare un casting corretto: non possiamo trasformare un gatto in un libro! E' anche chiaro che il compilatore non sa, nel momento in cui compilera' questo codice, cosa conterra' effettivamente il vettore v al momento dell'esecuzione; per cui il codice e' considerato corretto. Se al momento dell'esecuzione l'oggetto posto nella prima posizione del vettore non e' un libro si avra' l'errore ClassCastException.
21
Fisica Computazionale I - 421 Si potrebbe pensare che questo comporta dei limiti e delle restrizioni: cosa succede se non conosciamo la natura dell'oggetto che ci accingiamo ad estrarre? La potenza di Java ci consente di risolvere facilmente questo problema. Immaginiamo di avere un Vector vv, che contiene vari esemplari di oggetti diversi, per esempio libri, quaderni, penne....(istanze delle classi Libro, Quaderno, Penna....) in numero indefinito. Ecco come possiamo estrarre tutti gli oggetti:
22
Fisica Computazionale I - 422 int isize = vv.size(); // isize ci dice quanto e' lungo il vettore int i = 0; while(i < isize) { Object o = (Object)vv.elementAt(i); if(o instanceof Libro) { Libro l = (Libro)vv.elementAt(i);................... } if(o instanceof Quaderno) { Quaderno q = (Quaderno)vv.elementAt(i);................... } ++i; }
23
Fisica Computazionale I - 423 CLASSI ASTRATTE E METODI ASTRATTI Un metodo puo' essere dichiarato con il modificatore abstract per indicare che esso e' semplicemente un prototipo, privo di corpo. La dichiarazione e' seguita solo da un punto e virgola. Per esempio: abstract void MetodoAstratto(String name);
24
Fisica Computazionale I - 424 Una classe che contiene uno o piu' metodi astratti deve essa stessa essere dichiarata astratta, con il modificatore abstract: abstract class EsempioAstratto{........ abstract void MetodoAstratto(String name);........ }
25
Fisica Computazionale I - 425 Una classe astratta puo' contenere anche metodi non- astratti (cioe' normali), ma non puo' essere istanziata. Puo' invece essere utilizzata creando una sottoclasse di essa, cioe' con il meccanismo dell'ereditarieta'. I metodi astratti devono essere sostituiti da metodi dotati di un corpo. Non e' necessario implementare tutti i metodi astratti, ma, in tal caso, anche la nuova sottoclasse dovra' essere dichiarata astratta. In sostanza le classi astratte costituiscono dei telai di riferimento, dei modelli, da riempire di contenuti a cura dell'utilizzatore. Avremo modo in futuro, di utilizzare questo tipo di classi.
26
Fisica Computazionale I - 426 INTERFACCE Java espande il concetto di metodi astratti attraverso le interfacce (interfaces). E' spesso utile poter definire un gruppo di metodi astratti che definiscono un qualche comportamento per un oggetto, senza tuttavia legare cio' ad una implementazione concreta. Un interfaccia definisce un'insieme di metodi che una classe deve implementare. Una classe quindi puo' dichiarare che essa implementa un interfaccia se essa implementa i metodi richiesti. Un'interfaccia si presenta come una serie di metodi astratti. Per esempio:
27
Fisica Computazionale I - 427 public interface Guidabile{ boolean accendiMotore(); void spegniMotore(); boolean gira(Direction dir); } abbiamo definito l'interfaccia Guidabile, con tre metodi.
28
Fisica Computazionale I - 428 Ora possiamo definire la classe Automobile: public class Automobile implements Guidabile{................... public boolean accendiMotore() {................... } public void spegniMotore() {................... } public boolean gira(Direction dir) {................... }
29
Fisica Computazionale I - 429 Adesso possiamo definire la classe Autocarro, che di nuovo implementa la stessa interfaccia, ma non necessariamente allo stesso modo. public class Autocarro implements Guidabile{................... public boolean accendiMotore() {................... } public void spegniMotore() {................... } boolean gira(Direction dir) {................... }
30
Fisica Computazionale I - 430 In sostanza abbiamo ottenuto effetti non molto diversi da quelli che avremmo potuto ottenere definendo una qualche superclasse Veicolo e due sottoclassi Automobile e Autocarro. La differenza pero' e' nel fatto che ora, pur avendo caratteristiche diverse, Automobile ed Autocarro appartengono entrambe alla classe Guidabile. Cio' puo' essere sfruttato nel senso e' possibile definire variabili di tipo Guidabile e istanziarle con automobili o autocarri
31
Fisica Computazionale I - 431................... Automobile auto = new Automobile(); Autocarro camion = new Autocarro(); Guidabile veicolo;................... veicolo = auto; veicolo.accendiMotore();................... veicolo = camion; veicolo.gira(dd);................... Anche in questo caso, avremo modo in futuro di apprezzare i vantaggi di questo meccanismo, con cui e' possibile realizzare ereditarieta' multiple.
32
Fisica Computazionale I - 432 Il RIFERIMENTO this La parola riservata this indica in Java il riferimento all'oggetto corrente. In genere non e' necessario usare questa parola: il riferimento all'oggetto corrente e' implicito. Quando invochiamo un metodo, con l'istruzione compute(); e' implicito che vogliamo eseguire il metodo compute() di questo oggetto. Lo stesso dicasi quando usiamo le variabili di istanza.
33
Fisica Computazionale I - 433 Ma puo' accadere che, all'interno di un metodo, sia necessario fare riferimento all'oggetto corrente nel suo complesso, o meglio, alla specifica istanza. Cio' avviene quando, ad esempio vogliamo passare a qualche altro metodo il riferimento all'oggetto corrente. Possiamo fare cio' utilizzando il riferimento this. Vedremo in seguito alcuni casi in cui e' necessario utilizzare this.
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.