Definizione di una classe ¯ Creazione di una classe class LaMiaClasse { ... } ¯ Creazione di una sottoclasse class LaMiaClasse extends LaMiaSuperClasse { ... } ¯ Se la classe realizza una specifica interfaccia class LaMiaClasse implements Runnable { ... } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 1 JAVA Definizione di variabili di istanza, di costanti e di variabili di classe Le variabili di istanza sono dichiarate in una definizione di classe, esternamente alle dichiarazioni di metodi (si distinguono dalle variabili locali sulla base della loro posizione, poichè le variabili locali sono dichiarate all’interno dei metodi). class Bicycle extends PersonPoweredVehicle { String bikeType; int chainGear; int rearCogs; } Le costanti (final), variabili con un valore che non viene mai modificato, possono essere solo variabili di istanza o di classe, mai variabili locali. final float pi = 3.141592 final boolean debug = false; final int maxsize = 40000; final int LEFT = 0 ; final int RIGHT = 1; final int CENTER = 2; Non esistono i costrutti #define e const del C e C++. Le variabili di classe (static) appartengono a tutti gli oggetti della classe, non alle singole istanze. static int sum; static final int maxObjects = 10; Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 2 JAVA Creazione di un metodo I metodi definiscono i comportamenti degli oggetti. La definizione di un metodo richiede la definizione di: ¯ un nome ¯ un tipo (oggetto, o primitivo, o void) che il metodo ritorna µ se ritorna un oggetto di un certo tipo, nel corpo del metodo deve essere presente una istruzione return ¯ una lista di parametri µ i parametri sono variabili locali nel corpo del metodo ¯ il corpo del metodo Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 3 JAVA Creazione di un metodo Esempio class RangeClass { int[] makeRange (int lower, int upper) { int arr[] = new int[ (upper - lower) + 1 ]; for (int i = 0; i < arr.length; i++) { arr[i] = lower++; } return arr; } La “segnatura” (signature) è la combinazione di ¯ nome del metodo ¯ tipo del valore che ritorna ¯ lista di parametri µ la segnatura identifica in modo univoco un metodo (non basta il nome!) Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 4 JAVA La parola chiave this Permette di far riferimento all’oggetto corrente nel corpo della definizione di un metodo. t = this.x; // assegna a t la variabile di istanza x //di questo oggetto this.myMethod(this); // chiama il metodo myMethod definito in questa // classe, passandogli questo oggetto come parametro return this; // ritorna l’oggetto corrente ¯ È implicito quando si fa riferimento a variabili di istanza o a metodi. t = x; myMethod(this); ¯ this si riferisce all’istanza corrente µ non ha senso usarlo per i metodi o le variabili di classe Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 5 JAVA Visibilità delle variabili Quando si fa riferimento ad una variabile nella definizione di un metodo, Java cerca la definizione della variabile: 1. all’interno del blocco di istruzioni che contiene la variabile (variabile locale) 2. all’interno del metodo che contiene il blocco (variabile locale) 3. all’interno della classe che contiene il metodo (variabile di istanza o di classe) 4. all’interno di tutte le superclassi “antenate” della classe corrente µ Definizioni successive di variabili con lo stesso nome di variabili già presenti possono nascondere le variabili di livello gerarchico “superiore”. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 6 JAVA Visibilità delle variabili: esempio class ScopeTest { int test = 10; void print_test () { System.out.println("test = " + test); } void printTest () { int test = 20; System.out.println("test = " + test); } public static void main (String arg[]) { ScopeTest obj = new ScopeTest(); obj.print_test(); obj.printTest(); obj.print_test(); } } µ L’uso della parola chiave this permette di risolvere l’ambiguità tra variabili locali e variabili d’istanza o di classe. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 7 JAVA Passaggio di parametri ai metodi ¯ I tipi primitivi sono passati per valore (by value). ¯ Gli oggetti sono passati per indirizzo (by reference). µ sono modificati gli oggetti originali Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 8 JAVA Esempio: passaggio di parametri ai metodi class PassByReference { int OnetoZero (int arg[]) { int count = 0; for (int i = 0; i < arg.length; i++) { if (arg[i] == 1) { count++; arg[i] = 0; } } return count; } public static void main (String arg[]) { int arr[] = { 1, 3, 4, 5, 1, 1, 7 }; PassByReference test = new PassByReference(); int numOnes; System.out.print("Values of the array: [ "); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println("]"); numOnes = test.OnetoZero(arr); System.out.println("Number of Ones = " + numOnes); System.out.print("New values of the array: ["); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(" ]"); } } Values of the array: [ 1 3 4 5 1 1 7 ] Number of Ones = 3 New values of the array: [ 0 3 4 5 0 0 7 ] Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 9 JAVA Metodi di classe I metodi di classe sono definiti mediante la parola chiave static. static int max (int arg1, int arg2) { ... } ¯ sono utilizzabili anche in assenza di una istanza della classe ¯ Esempio: metodi di classe forniti nelle librerie Java. – nella classe Math float root = Math.sqrt(453.0); System.out.print("The larger of x and y is " + Math.max(x,y)); – nella classe Integer int count = Integer.parseInt("42", 10); // ritorna 42 Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 10 JAVA Creazione di una applicazione Java Una applicazione Java è composta da una o più classi; può essere molto semplice o molto elaborata (ad esempio il browser HotJava). Per ottenere una applicazione funzionante ¯ Una classe costituisce il punto di partenza dell’applicazione ¯ La classe di partenza deve contenere il metodo main(), la cui segnatura è: public static void main (String arg[]) { .... } ¯ Il metodo main è eseguito quando inizia l’esecuzione dell’applicazione main() è un metodo di classe µ la classe che lo contiene non è automaticamente istanziata Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 11 JAVA Passaggio di parametri ad applicazioni Il passaggio dei parametri avviene semplicemente scrivendo i parametri sulla linea di comando dopo il nome dell’applicazione. java MyProgram argument1 2 three java myprogram "Java e‘ carino" ¯ I parametri sono memorizzati in un array di stringhe, che è passato come parametro al metodo main() dell’applicazione. ¯ Java non controlla in modo automatico che sia passato all’applicazione il numero corretto di parametri. Se necessario, ciò va fatto nel codice dell’applicazione. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 12 JAVA Passaggio di parametri ad applicazioni ¯ Esempio: class EchoArgs { public static void main(String args[]) { for (int i=0; i < args.length; i++) { System.out.println("Argument" + i + ": " + args[i]); } } } ¯ Al contrario del linguaggio C, args[0] contiene il primo parametro, non il nome del programma! ¯ I parametri sono stringhe! µ per trattarli in modo diverso, bisogna convertirli Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 13 JAVA Polimorfismo dei metodi Java prevede l’overloading dei metodi: si possono creare metodi con lo stesso nome ma con diversa segnatura e diversa definizione. L’overloading dei metodi permette di: ¯ mantenere una interfaccia più semplice verso altri oggetti (non sono definiti metodi diversi che facciano più o meno la stessa cosa) ¯ avere comportamenti diversi a seconda dei parametri di ingresso del metodo Per creare un metodo overloaded, è sufficiente creare metodi diversi con lo stesso nome ma con una lista di parametri differente. A fronte di una chiamata ad un metodo, Java cerca il metodo con la segnatura corretta (stesso nome, numero e tipo di parametri) ed esegue il codice corrispondente. Attenzione: Il tipo del parametro di ritorno non conta! Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 14 JAVA Un esempio di overloading import java.awt.Point; class int int int int void printRect(){ System.out.print("MyRect: <" + x1 + ", " + y1); System.out.println(", " + x2 + ", " + y2 + ">"); } MyRect { x1 = 0; y1 = 0; x2 = 0; y2 = 0; public static void main (String args[]) { MyRect rect = new MyRect(); MyRect buildRect(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; return this; } MyRect buildRect(Point topLeft, Point bottomRight) { x1 = topLeft.x; y1 = topLeft.y; x2 = bottomRight.x; y2 = bottomRight.y; return this; } MyRect buildRect(Point topLeft, int w, int h) { x1 = topLeft.x; y1 = topLeft.y; x2 = (x1 + w); y2 = (y1 + h); return this; } System.out.println("Calling buildRect with coordinates 25,25 50,50:"); rect.buildRect(25, 25, 50, 50); rect.printRect(); System.out.println("----------"); System.out.println("Calling buildRect with points (10,10), (20,20):"); rect.buildRect(new Point(10,10), new Point(20,20)); rect.printRect(); System.out.println("----------"); System.out.print("Calling buildRect with 1 point (10,10),"); System.out.println(" width (50) and height (50)"); rect.buildRect(new Point(10,10), 50, 50); rect.printRect(); System.out.println("----------"); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 15 JAVA I metodi costruttori Un metodo costruttore è un metodo speciale che esegue l’inizializzazione di un oggetto. Il costruttore è un metodo che inizializza una istanza di una classe ¯ inizializza le variabili dell’oggetto ¯ crea eventuali altri oggetti necessari ¯ esegue tutte le operazioni necessarie alla “vita” dell’oggetto Quando si crea una nuova istanza di un classe con una chiamata new, Java ¯ alloca la memoria necessaria per l’oggetto ¯ inizializza le variabili di istanza dell’oggetto (al valore iniziale o di default) ¯ chiama il metodo costruttore della classe µ se il metodo costruttore non è definito, Java inserisce un metodo costruttore di default (senza argomenti) che chiama il costruttore della classe gerarchicamente superiore Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 16 JAVA I metodi costruttori I metodi costruttori: ¯ hanno sempre lo stesso nome della classe ¯ non hanno un valore di ritorno class Persona { String nome; int eta; public static void main (String args[]) { Persona p; p = new Persona("Laura", 20); } Persona (String n, int a) { nome = n; eta = a; } } Se il nuovo metodo costruttore da definire aggiunge alcune inizializzazioni specifiche, ma condivide il comportamento di un altro metodo costruttore della stessa classe µ inserire una chiamata a questo metodo, utilizzando il costrutto: this(arg1, arg2, arg3) È possibile avere overloading anche dei metodi costruttori. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 17 JAVA Metodi costruttori: esempio import java.awt.Point; class int int int int MyRect2(Point topLeft, int w, int h) { x1 = topLeft.x; y1 = topLeft.y; x2 = (x1 + w); y2 = (y1 + h); } MyRect2 { x1 = 0; y1 = 0; x2 = 0; y2 = 0; void printRect(){ System.out.print("MyRect: <" + x1 + ", " + y1); System.out.println(", " + x2 + ", " + y2 + ">"); } MyRect2(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } MyRect2(Point topLeft, Point bottomRight) { x1 = topLeft.x; y1 = topLeft.y; x2 = bottomRight.x; y2 = bottomRight.y; } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 18 JAVA Metodi costruttori: esempio public static void main (String args[]) { MyRect2 rect; System.out.println("Calling MyRect2 with coordinates 25,25 50,50:"); rect = new MyRect2(25, 25, 50,50); rect.printRect(); System.out.println("----------"); System.out.println("Calling buildRect w/points (10,10), (20,20):"); rect= new MyRect2(new Point(10,10), new Point(20,20)); rect.printRect(); System.out.println("----------"); System.out.print("Calling buildRect w/1 point (10,10),"); System.out.println(" width (50) and height (50)"); rect = new MyRect2(new Point(10,10), 50, 50); rect.printRect(); System.out.println("----------"); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 19 JAVA Ereditarietà di un metodo class PrintClass { int x = 0; int y = 1; void printMe() { System.out.println("X is " + x + ", Y is " + y); System.out.println("I am an instance of class " + this.getClass().getName()); } } class PrintSubClass extends PrintClass { int z=3; public static void main (String arg[]) { PrintSubClass obj = new PrintSubClass(); obj.printMe(); } } X is 0, Y is 1 I am an instance of the class PrintSubClass Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 20 JAVA Overriding di un metodo Se creo in una sottoclasse un metodo con la stessa segnatura di un metodo di una delle superclassi, il metodo originale non sarà più eseguito per le istanze di oggetti della classe. µ Permette di modificare il comportamento di un metodo. Esempio: se volessi stampare anche il valore della variabile di istanza z, potrei usare un overriding del metodo printMe(). class PrintSubClass2 extends PrintClass { int z=3; void printMe() { System.out.println("X is " + x + ", Y is " + y + ", Z is " + z ); System.out.println("I am an instance of class " + this.getClass().getName() ); } public static void main (String arg[]) { PrintSubClass2 obj = new PrintSubClass2(); obj.printMe(); } } X is 0, Y is 1, Z is 3 I am an instance of the class PrintSubClass2 Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 21 JAVA Overriding di un metodo µ Permette di aggiungere comportamenti a quelli forniti da un altro metodo. Esempio: per evitare la duplicazione del codice nei due metodi printMe(), posso richiamare il metodo della superclasse all’interno della sottoclasse, usando la parola chiave super. // from PrintClass void printMe() { System.out.println("I am an instance of class " + this.getClass().getName() ); System.out.println("X is " + x); System.out.println("Y is " + y); } // from PrintSubClass2 void printMe() { super.printMe(); System.out.println("Z is " + z); } I am an instance of the class PrintSubClass2 X is 0 Y is 1 Z is 3 Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 22 JAVA Overriding di un costruttore? Tecnicamente non è possibile: poiché i costruttori hanno lo stesso nome della classe, tutte le volte che si crea una sottoclasse si definisce un nuovo costruttore. Ogni volta che si crea una istanza di una classe sono chiamati (implicitamente) i costruttori di tutte le superclassi µ è chiamato il costruttore di “default” senza parametri È possibile richiamare all’interno del costruttore della sottoclasse il costruttore della superclasse, utilizzando la parola chiave super. µ è possibile specificare quale tra i costruttori delle superclassi utilizzare µ si possono modificare le inizializzazioni fatte sulle variabili di istanza proprie delle superclassi import java.awt.Point; class NamedPoint extends Point { String name; NamedPoint (int x, int y, String name) { super(x,y); this.name = name; } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 23 JAVA Metodo finalizer È il metodo chiamato da Java quando, durante la fase di garbage collection, si elimina un oggetto e si libera la memoria fino ad allora occupata dall’oggetto. Per creare un metodo finalizer, si crea un metodo con la seguente segnatura: void finalize() { .... } Il metodo finalize() viene chiamato automaticamente solo nel momento in cui la memoria occupata dall’oggetto è davvero liberata, non nel momento in cui tutti i riferimenti ad esso sono scomparsi. È possibile chiamare il metodo finalize() in modo esplicito all’interno di un programma µ questo non significa liberare la memoria occupata dall’oggetto che sarà automaticamente liberata da Java solo quando tutti i riferimenti correnti all’oggetto sono cancellati Il metodo finalize() serve soprattutto per cancellare riferimenti ad altri oggetti puntati dall’oggetto che si vuole cancellare. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino CREAZIONE DI APPLICAZIONI JAVA – 24 JAVA