Capitolo 7 Programmazione con metodi e classi Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Metodi Metodo istanza Opera su un oggetto (vale a dire un'istanza della classe) String s = new String("Help every cow reach its " + "potential!"); int n = s.length(); Metodo istanza Metodo di classe Servizio fornito da una classe che non è associato a un particolare oggetto String t = String.valueOf(n); Metodo di classe Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Campi dati Variabile istanza e costanti istanza Attributo di un particolare oggetto Solitamente una variabile Point p = new Point(5, 5); int px = p.x; Variabile istanza Variabile e costanti di classe Informazioni collettive che non sono specifiche per i singoli oggetti della classe Solitamente una costante Color favoriteColor = Color.MAGENTA; double favoriteNumber = MATH.PI - MATH.E; Costanti di classe Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività - Conversion.java Supporta la conversione tra valori anglosassoni e metrici d degrees Fahrenheit = (d -32)/1.8 degrees Celsius 1 mile = 1.609344 kilometers 1 gallon = 3.785411784 liters 1 ounce (avdp) = 28.349523125 grams 1 acre = 0.0015625 square miles = 0.40468564 hectares Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione della conversione public class Conversion // equivalenze per la conversione private static final double KILOMETERS_PER_MILE = 1.609344; private static final double LITERS_PER_GALLON = 3.785411784; private static final double GRAMS_PER_OUNCE = 28.349523125; private static final double HECTARES_PER_ACRE = 0.40468564; Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione della conversione // metodi di conversione della temperatura public static double fahrenheitToCelsius(double f) return (f - 32) / 1.8; } public static double celsiusToFahrenheit(double c) return 1.8 * c + 32; } // metodi di conversione della lunghezza public static double kilometersToMiles(double km) return km / KILOMETERS_PER_MILE; } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione della conversione Il modificatore classi possono utilizzare Modifier public public indicatindica es ot che her altre classes can use t he met hod questo metodo Il modificatore static indica che questo metodo è un Modifier stclasse at ic indicat es t he met hod is a class met hod metodo di public static double fahrenheitToCelsius(double f) { return (f - 32) / 1.8; } Si noti che il metodo contiene unat attributo Observe t here is no non reference in tun heriferimento met hod t oaan t ribut ediof un oggetto Conversion implicito (ossia, manca la parola chiave an implicit Conversion object (i.e., a "t his" object ). This absence "this"). Questa assenza è una caratteristica tipica dei metodi di is a class hod requirement . Class met hods aare classe, che met vengono invocati senza far riferimento uninvoked particolare oggetto wit hout respect t o any part icular object Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione della conversione // metodi di conversione della massa public static double litersToGallons(double liters) return liters / LITERS_PER_GALLON; } public static double gallonsToLiters(double gallons) return gallons * LITERS_PER_GALLON; } public static double gramsToOunces(double grams) return grams / GRAMS_PER_OUNCE; } public static double ouncesToGrams(double ounces) return ounces * GRAMS_PER_OUNCE; } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione della conversione // metodi di conversione dell'area public static double hectaresToAcres(double hectares) return hectares / HECTARES_PER_ACRE; } public static double acresToHectares(double acres) return acres * HECTARES_PER_ACRE; } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo della conversione BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Enter a length in kilometers: "); double kilometers = Double.parseDouble(stdin.readLine()); System.out.print("Enter a mass in liters: "); double liters = Double.parseDouble(stdin.readLine()); System.out.print("Enter a mass in grams: "); double grams = Double.parseDouble(stdin.readLine()); System.out.print("Enter an area in hectares: "); double hectares = Double.parseDouble(stdin.readLine()); double double double double miles = Conversion.kilometersToMiles(kilometers); gallons = Conversion.litersToGallons(liters); ounces = Conversion.gramsToOunces(grams); acres = Conversion.hectaresToAcres(hectares); Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo della conversione System.out.println(kilometers + " kilometers = " + miles + " miles "); System.out.println(liters + " liters = " + gallons + " gallons"); System.out.println(grams + " grams = " + ounces + " ounces"); System.out.println(hectares + " hectares = " + acres + " acres"); 2.0 3.0 4.0 5.0 kilometers = 1.242742384474668 miles liters = 0.7925161570744452 gallons grams = 0.14109584779832166 ounces hectares = 12.355269141746666 acres Java – Guida alla programmazione - James Cohoon, Jack Davidson Utilizzo preferito della conversione Copyright © 2004 - The McGraw-Hill Companies srl Parte di java.text NumberFormat style = NumberFormat.getNumberInstance(); style.setMaximumFractionDigits(2); style.setMinimumFractionDigits(2); System.out.println(kilometers + " kilometers = " + style.format(miles) + " miles "); System.out.println(liters + " liters = " + style.format(gallons) + " gallons"); System.out.println(grams + " grams = " + style.format(ounces) + " ounces"); System.out.println(hectares + " hectares = " + style.format(acres) + " acres"); 2.0 3.0 4.0 5.0 kilometers = 2,00 km liters = 0,79 gallons grams = 0,14 ounces hectares = 12.36 acres Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Invocazioni dei metodi I parametri effettivi forniscono informazioni altrimenti non disponibili per un metodo Quando viene invocato un metodo Java riserva la memoria per quella particolare invocazione Viene chiamato il record di attivazione Il record di attivazione memorizza, tra le altre cose, i valori dei parametri formali I parametri formali inizializzati con i valori dei parametri effettivi Dopo l'inizializzazione, i parametri effettivi e i parametri formali sono indipendenti gli uni dagli altri Il flusso di controllo è trasferito temporaneamente a quel metodo Java – Guida alla programmazione - James Cohoon, Jack Davidson Dimostrazione del passaggio di parametri per valore Copyright © 2004 - The McGraw-Hill Companies srl public class Demo public static double add(double x, double y) double result = x + y; return result; } public static double multiply(double x, double y) x = x * y; return x; } public static void main(String[] args) double a = 8, b = 11; double sum = add(a, b); System.out.println(a + " + " + b + " = " + sum); double product = multiply(a, b); System.out.println(a + " * " + b + " = " + product); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Dimostrazione del passaggio di parametri per valore Copyright © 2004 - The McGraw-Hill Companies srl multiply() non cambia il parametro effettivo Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Demo.java double sum = add(a, b); Init ial values paramet I valori iniziali of deiformal parametri formaliers derivano dai tparametri come from he act ualeffettivi paramet ers public static double add(double x, double y) { double result = x + y return result; } main() add() a 8.0 b sum product x 8.0 11.0 y 11.0 19.0 - result 19.0 - - Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Demo.java double multiply = multiply(a, b); Init ial values paramet I valori iniziali of deiformal parametri formaliers derivano dai tparametri come from he act ualeffettivi paramet ers public static double multiply(double x, double y) { x = x + y return x; } main() multiply() a 8.0 b 11.0 sum 19.0 product 88.0 - x 88.0 8.0 y 11.0 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public class PassingReferences public static void f(Point v) v = new Point(0, 0); } public static void g(Point v) v.setLocation(0, 0); } public static void main(String[] args) Point p = new Point(10, 10); System.out.println(p); f(p); System.out.println(p); g(p); System.out.println(p); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Esecuzione di PassingReferences.java g() può cambiare gli attributi dell’oggetto a cui p fa riferimento Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public static void main(String[] args){ Point p = new Point(10, 10); System.out.println(p); f(p); main() Point p y: 10 x: 10 f() v java.awt.Point[x=10,y=10] Met hod main()'s variable p La variabile p del metodo and met hod formal main() e ilf()'s parametro paramet er vdel have t he same formale metodo f() hanno loisstesso valore, value, which a reference to che è un riferimento an object represent inga un oggetto locat che ion (1rappresenta 0, 10) la posizione (10,10) Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public static void f(Point v) { v = new Point(0, 0); } main() Point p y: 10 x: 10 f() Point v y: 0 x: 0 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public static void main(String[] args){ Point p = new Point(10, 10); System.out.println(p); f(p); main() Point p y: 10 x: 10 g() System.out.println(p); g(p); v java.awt.Point[x=10,y=10] java.awt.Point[x=10,y=10] Met hod main()'s variable p La variabile p del metodo and met hod formal main() e ilg()'s parametro paramet er vdel have t he same formale metodo f() hanno loisstesso valore, value, which a reference to che è un riferimento an object represent inga un oggetto locat che ion (1rappresenta 0, 10) la posizione (10,10) Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public static void g(Point v) { v.setLocation(0, 0); } main() Point p y: y: 10 0 x: x: 10 0 g() v Met hod main()'s variable p La variabile p del metodo and met hod formal main() e ilg()'s parametro paramet er vdel have t he same formale metodo f() hanno loisstesso valore, value, which a reference to che è un riferimento an object represent inga un oggetto locat che ion (1rappresenta 0, 10) la posizione (10,10) Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl PassingReferences.java public static void main(String[] args){ Point p = new Point(10, 10); System.out.println(p); f(p); main() Point p y: 0 System.out.println(p); g(p); System.out.println(p); java.awt.Point[x=10,y=10] java.awt.Point[x=10,y=10] java.awt.Point[x=0,y=0] x: 0 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività - Triple.java Rappresenta gli oggetti con tre attributi interi public Triple() Costruisce un valore Triple predefinito che rappresenta tre zeri public Triple(int a, int b, int c) Costruisce una rappresentazione dei valori a, b e c public int getValue(int i) Restituisce l'iesimo elemento del Triple associato public void setValue(int i, int value) Imposta l'iesimo elemento del Triple associato sul valore Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività - Triple.java Rappresenta gli oggetti con tre attributi interi public String toString() Restituisce una rappresentazione di testo del Triple associato public Object clone() Restituisce un nuovo Triple la cui rappresentazione è la stessa del triple associato public boolean equals(Object v) Indica se v è equivalente al Triple associato Questi tre metodi sono prevalenze sui metodi ereditati Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione di Triple.java // Triple(): default constructor public Triple() { this(0, 0, 0); } The new Triple object (t he t his object ) is const ruct ed Il nuovo oggetto Triple (l'oggetto this) viene by invoking invocando t he Triple const ruct or expect ing tche hreesiint costruito il costruttore Triple values astre act valori ual paramet ers parametri effettivi aspetta int come public Triple() { int a = 0; int b = 0; int c = 0; this(a, b, c); } Illegal t his() invocat A t his() invocat ion Invocazione this()ion. illegale. Un'invocazione deve essere must begin it s st this() at ement body all'inizio del corpo dell'istruzione Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione di Triple.java // Triple(): costruttore specifico public Triple(int a, int b, int c) setValue(1, a); setValue(2, b); setValue(3, c); } // Triple(): costruttore specifico - definizione alternativa public Triple(int a, int b, int c) this.setValue(1, a); this.setValue(2, b); this.setValue(3, c); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione di Triple.java La classe Triple è simile a ogni altra classe Java Automaticamente un'estensione della classe standard Object La classe Object specifica alcuni comportamenti di base comuni a tutti gli oggetti Questi comportamenti sono ereditati Tre dei metodi Object ereditati toString() clone() equals() Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Raccomandazione Le classi dovrebbero avere la prevalenza (fornire un'implementazione specifica per la classe) toString() clone() equals() In questo modo può essere fornito il comportamento previsto dal programmatore System.out.println(p); System.out.println(q); // // // // versione stringa di oggetto referenziato da p versione stringa di oggetto referenziato da q Java – Guida alla programmazione - James Cohoon, Jack Davidson Implementazione di toString() per Triple.java Copyright © 2004 - The McGraw-Hill Companies srl public int int int String toString(){ a = getValue(1); b = getValue(2); c = getValue(3); return "Triple[" + a + ", " + b + ", " + c+ "]"); } Considerare Triple t1 = new Triple(10, 20, 30); System.out.println(t1); Triple t2 = new Triple(8, 88, 888); System.out.println(t2); Produce Triple[10, 20, 30] Triple[8, 88, 888] Java – Guida alla programmazione - James Cohoon, Jack Davidson Implementazione di clone() per Triple.java Copyright © 2004 - The McGraw-Hill Companies srl public int int int String clone() { a = getValue(1); b = getValue(2); c = getValue(3); return new Triple(a, b, c); } Considerare Triple t1 = new Triple(9, 28, 29); Triple t2 = (Triple) t1.clone(); System.out.println("t1 = " + t1); System.out.println("t2 = " + t2); Produce Triple[9, 28, 29] Triple[9, 28, 29] Deve eseguire la conversione! Java – Guida alla programmazione - James Cohoon, Jack Davidson Implementazione di equals() per Triple.java Copyright © 2004 - The McGraw-Hill Companies srl public boolean equals(Object v) if (v instanceof Triple) int a1 = getValue(1); int b1 = getValue(2); int c1 = getValue(3); Triple int a2 int b2 int c2 t = = = Non può essere uguale a meno che sia un Triple = (Triple) v; t.getValue(1); t.getValue(2); t.getValue(3); return (a1 == a2) && (b1 == b2) && (c1 == c2); } else return false; } } Confronta gli attributi corrispondenti Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Triple.java - equals() Triple e = new Triple(4, 6, 10); Triple f = new Triple(4, 6, 11);, Triple g = new Triple(4, 6, 10); Triple h = new Triple(4, 5, 11); boolean flag1 = e.equals(f); Triple e x1: 4 x2: 6 x3: 10 Triple f x1: 4 x2: 6 x3: 11 Triple g x1: 4 x2: 6 x3: 10 Triple h x1: 4 x2: 5 x3: 11 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Triple.java - equals() Triple e = new Triple(4, 6, 10); Triple f = new Triple(4, 6, 11);, Triple g = new Triple(4, 6, 10); Triple h = new Triple(4, 5, 11); boolean flag2 = e.equals(g); Triple e x1: 4 x2: 6 x3: 10 Triple f x1: 4 x2: 6 x3: 11 Triple g x1: 4 x2: 6 x3: 10 Triple h x1: 4 x2: 5 x3: 11 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Triple.java - equals() Triple e = new Triple(4, 6, 10); Triple f = new Triple(4, 6, 11);, Triple g = new Triple(4, 6, 10); Triple h = new Triple(4, 5, 11); boolean flag3 = g.equals(h); Triple e x1: 4 x2: 6 x3: 10 Triple f x1: 4 x2: 6 x3: 11 Triple g x1: 4 x2: 6 x3: 10 Triple h x1: 4 x2: 5 x3: 11 Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Che cosa non va? class Scope { public static void f(int a) { int b = 1; // definizione locale System.out.println(a); // stampa 10 a = b; // aggiorna a System.out.println(a); // stampa 1 } public static void main(String[] args){ int i = 10; // definizione locale f(i); // invoca f() con i come parametro System.out.println(a); System.out.println(b); } } Le variabili a e b non esistono nell'ambito del metodo main() Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Regole per blocchi e ambito Un blocco è un elenco di istruzioni nidificate all'interno di parentesi graffe Il corpo di un metodo è un blocco Un blocco può essere posto ovunque sia consentita un'istruzione Un blocco contenuto in un altro blocco è un blocco nidificato Un parametro formale deve essere definito all'inizio del corpo del metodo Una variabile locale può essere utilizzata solo in un'istruzione o nei blocchi nidificati che seguono la sua definizione Un nome di identificatore può essere riutilizzato finché i blocchi che contengono le dichiarazioni duplicate non sono nidificati l'uno nell'altro Il riutilizzo del nome all'interno di un metodo è consentito finché avviene in blocchi distinti Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Consentito class Scope2 { public static void main(String[] args){ int a = 10; f(a); System.out.println(a); } public static void f(int a) { System.out.println(a); a = 1; System.out.println(a); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Consentito, ma sconsigliato public void g() { { int j = 1; System.out.println(j); } { int j = 10; // definisce j // stampa 1 // definisce un j differente System.out.println(j); // stampa 10 char j = '@'; // definisce un j } { differente System.out.println(j); } } // stampa '@' Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Qual è l'output? for (int i = 0; i < 3; ++i) { int j = 0; ++j; System.out.println(j); } L'ambito della variabile j è il corpo del ciclo for j non è nell'ambito durante ++i j non è nell'ambito quando i < 3 viene valutato j viene ridefinito e reinizializzato ad ogni iterazione nel ciclo Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Overloading È stato visto spesso con gli operatori int i = 11 + 28; double x = 6.9 + 11.29; String s = "April " + "June"; Java supporta anche l'overloading dei metodi Diversi metodi possono avere lo stesso nome Utile quando occorre scrivere metodi che eseguono attività simili ma con elenchi di parametri diversi Il nome del metodo può subire l'overloading finché la sua firma è diversa dagli altri metodi della sua classe Differenza nei nomi, nei tipi, nel numero o nell'ordine dei parametri Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Consentito public static int min(int a, int b, int c) return Math.min(a, Math.min(b, c)); } public static int min(int a, int b, int c, int d) return Math.min(a, min(b, c, d)); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Consentito public static int power(int x, int n) int result = 1; for (int i = 1; i <= n; ++i) result *= x; } return result; } public static double power(double x, int n) double result = 1; for (int i = 1; i <= n; ++i) result *= x; } return result; } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Qual è l'output? public static void f(int a, int b) { System.out.println(a + b); } public static void f(double a, double b) { System.out.println(a - b); } public static void main(String[] args){ int i = 19; double x = 54.0; f(i, x); }