SISSIS MODULO DI JAVA PER LA CLASSE IV DELL’ITI UNITA’ DIDATTICA 4 UN’ANALISI APPROFONDITA DEI METODI E DELLE CLASSI di Doretta Bonura Corso di fondamenti di Informatica: IV ciclo prof. Domenico Cantone
PREREQUISITI _____________________________________________ Familiarità in Java con: Tipi di dati Operatori Costrutti principali Concetto di classe e oggetti Struttura sintattica delle classi e dei metodi UD 4: I metodi in java
UN’ANALISI APPROFONDITA DEI METODI E DELLE CLASSI OBIETTIVI ________________________________________________________ Guidare lo studente ad acquisire una mentalità di programmazione O.O. mostrando le potenzialità degli strumenti di programmazione che Java mette a disposizione in questa direzione: LA PAROLA RISERVATA this SOVRACCARICO DEI METODI OGGETTI COME PARAMETRI EREDITARIETA’ RIDEFINIZIONE DEI METODI CLASSI ASTRATTE E METODI ASTRATTI UD 4: I metodi in java
STRUMENTI ________________________________________________________ LIBRO DI TESTO APPUNTI DEL PROFESSORE TUTORIAL SU INTERNET LABORATORIO Nota: testi di riferimento usati per queste slides: JAVA GUIDA COMPLETA - Patrick Naughton, Herbert Shildt – Mc Graw Hill JAVA GUDA COMPLETA – Laura Lemay, Charles L. Perkins - APOGEO UD 4: I metodi in java
METODOLOGIE DI LAVORO: _________________________________________________________ Lezione frontale Esercitazioni di laboratorio Esercitazioni in classe Esercitazioni a casa con esercizi e piccoli progetti. Verifiche in classe scritte e orali UD 4: I metodi in java
TEMPI TOTALE: 3 SETTIMANE ore Lezione frontale 8 Esercitazioni di laboratorio 9 Esercitazioni in classe 4 Verifiche in classe scritte e orali 6 Esercitazioni a casa 15 UD 4: I metodi in java
LA PAROLA RISERVATA this Nel corpo di un metodo può presentarsi la necessità di far riferimento all’oggetto corrente, cioè quello su cui verrà richiamato il metodo, quando l’oggetto verrà creato. In questi casi si usa la parola chiave this che permette di far riferimento all’oggetto corrente, prima ancora che esso venga istanziato. Esso puo’ essere usato in diverse situazioni: ------------------------------------------------------------------------------ Nei metodi costruttori. Per restituire l’oggetto stesso all’interno di un metodo. Per far riferimento da parte di un metodo ad un altro metodo dichiarato all’interno della stessa classe. ------------------------------------------------------------------------------------ Poiché il this è un riferimento all’istanza corrente di una classe lo si può utilizzare solo nei metodi si istanza, non nei metodi di classe (quelli dichiarati come static). L’omissione del this per far riferimento alle variabili di istanza nel corpo di un metodo è possibile se non esistono variabili locali con lo stesso nome delle variabili di istanza, altrimenti si farà precedere il riferimento alla variabile di istanza dalla parola riservata this. Vediamo subito un esempio. UD4: I metodi in java
UTILIZZO DEL this NEI METODI COSTRUTTORI //*************** file: Rettangolo.java public class Rettangolo { double base; // var di istanza double altezza; // var di istanza //----- metodo costruttore ----- Rettangolo( double b, double a) { base = b; altezza =a; } } //fine classe Rettangolo double base; // var di istanza double altezza; // var di istanza //----- metodo costruttore----- Rettangolo( double base, double altezza) { this.base = base; this.altezza = altezza; Nel primo riquadro, per assegnare un valore alle variabili di istanza base e altezza, si è dovuto assegnare un altro nome ai parametri del metodo costruttore, in quanto, se si assegnasse lo stesso nome, all’interno del metodo le variabile di istanza sarebbero mascherate e non sarebbero visibili. Nel secondo riquadro vediamo che le variabili di istanza e i parametri del metodo costruttore hanno lo stesso nome.Quindi la variabile locale nasconde la variabile di istanza. In realtà java permette di far riferimento alle variabili di istanza all’interno del metodo utilizzando il this. Queste due classi sono equivalenti e l’utilizzo o no del this nei metodi costruttori dipende dalle preferenze del programmatore. UD4: I metodi in java
UTILIZZO DEL this PER RESTITUIRE L’OGGETTO CORRENTE IN UN METODO //*************** file: Rettangolo.java public class Rettangolo { double base; // var di istanza double altezza; // var di istanza //----- metodo costruttore----- Rettangolo( double base, double altezza) { this.base = base; this.altezza =altezza; } //----- metodo cambiadimA ----- void cambiadimA( int scalare) { base = base * scalare; altezza =altezza * scalare; //----- metodo cambiadimB ----- Rettangolo cambiadimB( int scalare) { base = base * scalare; altezza = altezza * scalare; return this; //oggetto corrente } //fine classe Rettangolo I due metodi cambiadimA e cambiadimB eseguono le stesse operazioni però il primo non restituisce niente, mentre il secondo restituisce l’oggetto stesso. Nel main verranno richiamati con modalità diverse. //********** file: ProvaRettangolo.java ****** public class ProvaRettangolo { //----------------- metodo main --------------- public static void main ( String args[]) { Rettangolo r = new Rettangolo(1, 2); r.cambiadimA( 3 ); r = r.cambiadimB( 5 ); } //fine classe ProvaRettangolo UD4: I metodi in java
UTILIZZO DEL THIS PER FAR RIFERIMENTO AD UN ALTRO METODO ALL’INTERNO DELLA CLASSE STESSA //*************** file: Triangolo.java public class Triangolo { double a; // var di istanza double b; // var di istanza double c; // var di istanza //----- metodo costruttore con i lati come parametri Triangolo( double , double b, double c) { this.a = a; this.b = b; this.c = c; } //----- metodo perimetro ----- double perimetro( ) { return ( a+b+c ); //----- metodo area con formula di Erone double area ( ) { double area; double p; //semiperimetro p = this.perimetro( ) / 2; area = Math.sqrt( ( p-a) * (p-b) * (p-c) ); return area; } //fine classe Triangolo Nel riquadro accanto, all’interno del metodo area viene calcolato il semiperimetro utilizzando il metodo perimetro definito in un altro metodo della stessa classe. Il this permette quindi di far riferimento all’oggetto corrente prima che esso venga creato. //********** file: ProvaTriangolo.java ****** public class ProvaTriangolo { //----------------- metodo main --------------- public static void main( String args[ ]) { Triangolo t = new Triangolo(4, 5, 6); area = t.area( ); } //fine classe ProvaTriangolo Nel main posso richiamare il metodo area direttamente sull’oggetto t, Il metodo perimetro, richiamato dal metodo area sarà automaticamente eseguito sullo stesso oggetto t. UD4: I metodi in java
SOVRACCARICO (OVERLOAD) DEI METODI Il sovraccarico dei metodi è uno dei modi in cui Java implementa il polimorfismo. E’ possibile definire due o più metodi aventi lo stesso nome all’interno della stessa classe purché si distinguano per il numero dei parametri, nota bene: non per il tipo dei parametri o per il tipo di ritorno. Vediamo un esempio: UD4: I metodi in java
SOVRACCARICO DEI METODI esempio: //*************** file: Scrittura.java ***************************************************************** public class Scrittura { //--------------------------------------- metodo scrivi con 1 parametro ----- void scrivi( String s1) { System.out.println(s1); } //-------------------------------------metodo scrivi con 2 parametri ------ void scrivi( String s1, String s2) { System.out.println(s1+ s2); } //fine classe Scrittura //****************** file: ProvaScrittura.java ***************************************************** public class ProvaScrittura { //------------------------------------- metodo main --------------- public static void main void ( String args[ ]) { Scrittura frase = new Scrittura( ); //viene usato il metodo costruttore di default frase.scrivi(“Ciao a tutti”); frase.scrivi(”BUON NATALE ”,” FELICE ANNO NUOVO”); } // fine classe ProvaScrittura ______________________________________________________________ Questo programma genera il seguente output: Ciao a tutti BUON NATALE FELICE ANNO NUOVO UD4: I metodi in java
SOVRACCARICO DEI METODI COSTRUTTORI Il sovraccarico dei metodi costruttori segue le stesse regole dei metodi in generale, bisogna ricordare pero’ che il metodo costruttore di default, senza parametri non potrà più essere utilizzato. Si può ovviare a questo inconveniente ridefinendo il metodo costruttore di default. //*************** file: Punto.java *********************************************************** public class Punto { double x ; // variabili di istanza double y ; double z ; //------------------- metodo costruttore con 3 parametri ----------------------- Punto(double x, double y, double z) { // costruisce un punto nello spazio XYZ this.x = x; this.y = y; this.z = z; } //------------------- metodo costruttore con 2 parametri---------------- Punto( double x, double y) { // costruisce un punto nel piano Z=0 this.z = 0; //-------------------- metodo costruttore senza parametri ---------- Punto( ) { // ridefinizione del metodo costruttore di default, costruisce il punto origine this.x = 0; this.y = 0; } //----------------------------------------------------------------------------- } //fine classe Punto UD4: I metodi in java
SOVRACCARICO DEI METODI COSTRUTTORI Vediamo come vengono creati gli oggetti della classe Punto nel main //*************** file: ProvaPunto.java ********************************************************************* public class ProvaPunto { public static void main ( String args[]) { Punto origine = new Punto( ); //viene costruito l’oggetto Punto origine = (0,0,0) Punto p1_2d = new Punto(3,4); //viene costruito l’oggetto Punto p1_2d = (3,4,0) Punto p1_3d = new Punto(3,4,5); //viene costruito l’oggetto Punto p1_2d = (3,4,5) System.out.println(“Il punto p1_2d ha coordinate:”); System.out.println(“X = “ + p1_2d.x); System.out.println(“Y = “ + p1_2d.y); System.out.println(“Z = “ + p1_2d.z); } } // fine classe ProvaPunto ______________________________________________________________ Questo programma genera il seguente output: Il punto p1_2d ha coordinate: X = 3 Y = 4 Z = 0 UD4: I metodi in java
UTILIZZO DEGLI OGGETTI COME PARAMETRI E’ possibile passare degli oggetti ai metodi //*************** file: Circonferenza.java public class Circonferenza { Punto centro; // var di istanza double raggio ; // var di istanza // metodo costruttore riceve come parametri // un oggetto Punto e un tipo double. Circonferenza( Punto centro, double r){ this.centro = centro; this.raggio = raggio; } // metodo costruttore di default, costruisce // la circonferenza goniometrica Circonferenza( ){ centro = new Punto( ); raggio = 1; } // fine classe Circonferenza //*************** file: ProvaCirconferenza.java public class ProvaCirconferenza { public static void main ( String args[ ]) { Punto centroA = new Punto(3,4); // Punto a = (3,4,0) Circonferenza cirA = new Circonferenza(centroA , 8); Circonferenza cirB = new Circonferenza( ); } // fine classe ProvaCirconferenza L’oggetto centroA della classe Punto viene prima creato e poi passato come parametro attuale per costruire l’oggetto cirA della classe Circonferenza I tipi semplici in java sono passati automaticamente per valore, cioè viene fatta una copia. Gli oggetti invece vengono passati automaticamente per riferimento. Questo vuol dire che se un oggetto viene passato come parametro ad un metodo che ne cambia le caratteristiche è l’oggetto stesso che viene cambiato. Vediamo un esempio: UD4: I metodi in java
GLI OGGETTI SONO PASSATI AUTOMATICAMENTE PER RIFERIMENTO Esempio: //*************** file: ManipolaPunti.java public class ManipolaPunti { // metodo static che sposta il punto passato come // parametro di un quantita’ s public static void sposta (Punto p, double s ){ p.x = p.x + s; p.y = p.y + s; p.z = p.z + s; } } // fine classe ManipolaPunti //*************** file: ProvaManipola.java public class ProvaManipola { public static void main ( String args[ ] ) { Punto p = new Punto(3,4); // Punto p =(3,4,0) // l’oggetto p viene passato come parametro attuale ManipolaPunti.sposta (p,2); System.out.println(“x = “ + p.x ); System.out.println(“y = “ + p.y ); System.out.println(“z = “ + p.z ); } // fine classe ProvaManipola L’output di questo programma sarà: x = 5 y = 6 z = 2 Come si vede dall’output, le coordinate di p sono cambiate. Ricorda che: anche le stringhe e gli array in Java sono oggetti e quindi vengono passati automaticamente per riferimento. UD4: I metodi in java
EREDITARIETA’ Java supporta il meccanismo dell’ereditarietà. E’ possibile specificare una sola superclasse per qualunque sottoclasse creata. E’ possibile creare una gerarchia di ereditarietà in cui una sottoclasse diventa superclasse di un’altra sottoclasse.
EREDITARIETA’ Una sottoclasse può accedere a tutti i membri della superclasse: variabili di istanza e metodi, che sono stati dichiarati come public o protected, ma non come private. Esempio: Estendiamo la classe Rettangolo con la classe Parallelepipedo. //*************** file: Rettangolo.java public class Rettangolo { double base; // var di istanza double altezza; // var di istanza //----- metodo costruttore----- Rettangolo( double base, double altezza) { this.base = base; this.altezza =altezza; } //----- metodo cambiadim ----- void cambiadim( int scalare) { base = base * scalare; altezza =altezza * scalare; } // fine classe Rettangolo //*************** file: Parallelepipedo.java public class Parallelepipedo extends Rettangolo{ double larghezza; //variabile di istanza //---- metodo costruttore con 3 parametri ------------ Parallelepipedo( double b, double a, double l ){ base =b; altezza = a; larghezza =l; //--------- metodo costruttore con 1 parametro ------- // costruisce il cubo Parallelepipedo( double lato ){ base = lato; altezza = lato; larghezza =lato; } // fine classe Parallelepipedo UD4: I metodi in java
UTILIZZO DI SUPER PER CHIAMARE I COSTRUTTORI DELLA SUPERCLASSE Supponiamo di voler dichiarare come private nella classe Rettangolo le variabili di istanza base e altezza, allora esse non saranno più accessibili dalla classe estesa Parallelepipedo, e non potranno più essere usate neanche dal metodo costruttore. Java fornisce un sistema per utilizzare il metodo costruttore della classe immediatamente sopra. //*************** file: Rettangolo.java public class Rettangolo { double base; // var di istanza double altezza; // var di istanza //----- metodo costruttore con 2 parametri Rettangolo( double b, double a) { base = b; altezza =a; } //----- metodo costruttore con 1 parametro // costruisce il quadrato ---- Rettangolo( double lato) { base = lato; altezza = lato; //----- metodo cambiadim ----- void cambiadim( int scalare) { base = base * scalare; altezza =altezza * scalare; } // fine classe Rettangolo //*************** file: Parallelepipedo.java public class Parallelepipedo extends Rettangolo { private double larghezza; //variabile di istanza //---- metodo costruttore con 3 parametri Parallelepipedo( double b, double a, double l ){ super( b, a ); larghezza =l; //--- metodo costruttore con 2 parametri ------ Parallelepipedo( double lato, double l ){ super( lato ); //---- metodo costruttore con 1 parametro ------ // costruisce il cubo Parallelepipedo( double lato ){ larghezza =lato; } // fine classe Parallelepipedo UD4: I metodi in java
UTILIZZO DEI METODI DELLA CLASSE SUPERIORE Il metodo cambiadim nella classe Rettangolo può essere richiamato anche da un oggetto della classe parallelepipedo. //*************** file: ProvaParallelepipedo.java public class ProvaParallelepipedo { public static void main ( String args[ ]) { //posso creare oggetti con i diversi metodi costruttori Parallelepipedo p1 = new Parallelepipedo(3,4,5); // creo l’oggetto cubo di lato 3 Parallelepipedo cubo = new Parallelepipedo( 3 ); //applico ora il metodo cambiadim della classe superiore //Rettangolo cubo.cambiadim( 2 ); // Attenzione per poter accedere in questo modo alle variabili // di istanza, esse devono essere dichiarate come public System.out.println(“Dimensioni dell’oggetto cubo: “); System.out.println(“base = “ + cubo.base); System.out.println(“altezza = “ + cubo.altezza); System.out.println(“larghezza = “ + cubo.larghezza ); } } // Fine classe ProvaParallelepipedo L’output di questo programma sarà: Dimensioni dell’oggetto cubo: base = 6 altezza = 6 larghezza = 3 OSSERVA CHE: sono state modificate solo la base e l’altezza quindi l’oggetto cubo non è più un cubo. UD4: I metodi in java
UNA ALTERNATIVA AL SUPER UN OGGETTO DELLA SUPERCLASSE PUO’ ESSERE DICHIARATO COME VARIABILE DI ISTANZA NELLA SOTTOCLASSE E PUO’ ESSERE PASSATO COME PARAMETRO NEI METODI COSTRUTTORI DELLA SOTTOCLASSE //*************** file: ParallelepipA..java public class ParallelepipA extends Rettangolo { Rettangolo r; // variabile di istanza double larghezza; // variabile di istanza //---- metodo costruttore con 3 parametri ParallelepipA( double b, double a, double l ){ r = new Rettangolo(b,a); larghezza =l; } //--- metodo costruttore con 2 parametri ------ ParallelepipA( Rettangolo r1, double l ){ r = r1; //---- metodo costruttore con 1 parametro ------ // costruisce il cubo ParallelepipA( double lato ){ r = new Rettangolo( lato ); larghezza =lato; } // fine classe ParallelepipA Nel riquadro accanto nota che: Invece di ridichiarare la variabili base e altezza nella sottoclasse, dichiaro direttamente un oggetto Rettangolo come variabile di istanza. Il metodo costruttore con 2 parametri ha come parametro un oggetto della superclasse Rettangolo. //*************** file: ProvaParallelepipA.java public class ProvaParallelepipA { public static void main ( String args[ ]) { //istanziazione a partire dai 3 lati. ParallelepipA p1 = new ParallelepipA (3,4,5); // creo un oggetto r della classe Rettangolo Rettangolo r = new rettangolo(1,2); // e poi lo utilizzo nella costruzione di un oggetto della //classe Parallelepipedo ParallelepipA p2 = new ParallelepipA( r , 5 ); } // Fine classe ProvaParallelepipA _________________________________________ Per istanziare il ParallelepipA p2 abbiamo usato un oggetto della classe Rettangolo e la misura della larghezza. UD4: I metodi in java
RIDEFINIZIONE DEI METODI (OVERRIDE) Come si è visto negli esempi precedenti, quando si estende una classe può essere utile poter adeguare dei metodi alla struttura della classe estesa. Java permette di ridefinire i metodi. Questa è un’altra maniera in cui viene realizzato il polimorfismo. In una gerarchia di classi, quando un metodo di una sottoclasse ha lo stesso nome e lo stesso tipo di ritorno di un metodo della superclasse , si dice che il metodo nella sottoclasse ridefinisce (override) il metodo della superclasse. Quando un metodo ridefinito viene chiamato all’interno di una sottoclasse fa sempre riferimento alla versione ridefinita nella sottoclasse, il metodo della superclasse viene nascosto. I metodi ridefiniti consentono a Java di supportare il polimorfismo run-time (durante l’esecuzione). La capacità di richiamare metodi su istanze di nuove classi senza dove ricompilare è uno strumento di grande potenza. UD4: I metodi in java
RIDEFINIZIONE DEI METODI Esempio: estendiamo la classe Rettangolo con la sottoclasse Parallelepipedo e ridefiniamo il metodo cambiadim in modo che cambi le dimensioni senza deformare il parallelepipedo. //*************** file: Parallelepipedo.java public class Parallelepipedo extends Rettangolo { double larghezza; //variabile di istanza //metodo costruttore con 3 parametri Parallelepipedo( double b, double a, double l ){ super( b, a ); larghezza =l; } //metodo costruttore con 1 parametro, //costruisce il cubo Parallelepipedo( double lato ){ super( lato ); larghezza =lato; //ridefinizione del metodo cambiadim void cambiadim( int scalare) { base = base * scalare; altezza =altezza * scalare; larghezza = larghezza * scalare; } // fine classe Parallepipedo //*************** file: ProvaParallelepipedo.java public class ProvaParallelepipedo { public static void main ( String args[ ]) { // creo l’oggetto cubo di lato 3 Parallelepipedo cubo = new Parallelepipedo( 3 ); //applico ora il metodo cambiadim, verrà automaticamente //richiamato il metodo ridefinito nella sottoclasse cubo.cambiadim( 2 ); System.out.println(“Dimensioni dell’oggetto cubo: “); System.out.println(“base = “ + cubo.base); System.out.println(“altezza = “ + cubo.altezza); System.out.println(“larghezza = “ + cubo.larghezza ); } // fine classe ProvaParallepipedo _______________________________________________ L’output di questo programma sarà: Dimensioni dell’oggetto cubo: base = 6 altezza = 6 larghezza = 6 Il nostro cubo si è ingrandito ma non è stato deformato UD4: I metodi in java
CLASSI ASTRATTE E METODI ASTRATTI A volte si può desiderare definire una superclasse che dichiari una struttura astratta senza entrare nei dettagli dell’implementazione. Figura colore dim1 area( ) perimetro( ) intestazione( ) {...} area ( ) {...} perimetro( ) {...} dim2 dim3 area( ) {...} perimetro( ) {...} dim2 area( ) {...} perimetro( ) {...} Triangolo Rettangolo Cerchio UD4: I metodi in java
CLASSI ASTRATTE E METODI ASTRATTI E’ possibile anche che dei metodi non abbiano significato se non sono ridefiniti nelle sottoclassi. La soluzione che offre Java è il metodo astratto. //*************** file: Figura.java abstract class Figura{ String colore; // variabile di istanza double dim1; //variabile di istanza //------------- metodo costruttore concreto ------ Figura(String color, double d){ colore = new String( color ); dim1 = d; } //--------------- metodo astratto ----------------------- abstract double area( ) ; abstract double perimetro( ) ; //--------------- metodo concreto --------------------- void intestazione{ system.out.println(“Questa è una figura geometrica”); } // fine classe Figura Notare che: I metodi concreti sono permessi nelle classi astratte. Nei metodi astratti non è presente nessun corpo del metodo. Le sottoclassi sono obbligate a ridefinire tutti i metodi astratti della superclasse. UD4: I metodi in java
SOTTOCLASSI DELLE CLASSI ASTRATTE Definiamo le classi FigCerchio e FigRettangolo come sottoclassi della classe astratta Figura //*************** file: FigCerchio.java public class FigCerchio extends Figura{ //metodo costruttore FigCerchio( String color, double raggio) { super (color, raggio); } //ridefinizione del metodo area: obbligatoria double area( ) { return( dim1 * dim1 * 3.14 ); //ridefinizione del metodo perimetro: obbligatoria double perimetro( ) { return( 2 * dim1 * 3.14 ); } // fine classe FigCerchio _______________________________________ Nota che: il metodo perimetro va comunque ridefinito nonostante il nome più appropriato sia circonferenza. //*************** file: FigRettangolo.java public class FigRettangolo extends Figura { double dim2; // variabile di istanza FigRettangolo( String col, double d1,double d2) { super (col, d1); dim2= d2; return( dim1 * dim2); return( 2 * (dim1 + dim2)); } // fine classe FigRettangolo UD4: I metodi in java
ISTANZIAZIONE DI OGGETTI CON LE CLASSI ASTRATTE Le classi astratti non possono essere utilizzate per istanziare oggetti, però è possibile creare un riferimento della classe astratta ad un oggetto della sottoclasse. Vediamo come: //*************** file: ProvaFigura.java public class ProvaFigura { public static void main ( String args[ ]) { //Questo comando è illegale infatti è lasciato come commento //Figura F = new Figura(“Rosso”, 5); // posso invece creare un oggetto della sottoclasse FigCerchio FigCerchio c = new FigCerchio(“Rosso”, 5); //questa istruzione è ammessa, non sto creando nessun oggetto // ma una variabile di riferimento di tipo Figura Figura f1; // a questo punto è possibile assegnare l’oggetto di tipo FigCerchio // alla variabile di tipo Figura f1 = c; // posso ora richiamare i metodi sulla variabile di tipo figura // ATTENZIONE: f1e’ un riferimento, quindi tutte le modifiche su f1 si ripercuoteranno su c. system.out.println(“L’area e’ ” + f1.area( ) ); } } // fine classe ProvaFigura UD4: I metodi in java
FINE UD4: I metodi in java