Definizione di una classe ffl Creazione di una classe class LaMiaClasse {... ffl Creazione di una sottoclasse class LaMiaClasse extends LaMiaSuperClasse {... ffl Se la classe realizza una specifica interfaccia class LaMiaClasse implements Runnable {... CREAZIONE DI APPLICAZIONI 1 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 int LEFT = 0 ; final boolean debug = false; final int RIGHT = 1; final int maxsize = 40000; 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; CREAZIONE DI APPLICAZIONI 2
Creazione di un metodo I metodi definiscono i comportamenti degli oggetti. La definizione di un metodo richiede la definizione di: ffl un nome ffl 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 ffl una lista di parametri ) i parametri sono variabili locali nel corpo del metodo ffl il corpo del metodo CREAZIONE DI APPLICAZIONI 3 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 ffl nome del metodo ffl tipo del valore che ritorna ffl lista di parametri ) la segnatura identifica in modo univoco un metodo (non basta il nome!) CREAZIONE DI APPLICAZIONI 4
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 ffl È implicito quando si fa riferimento a variabili di istanza o a metodi. t = x; mymethod(this); ffl this si riferisce all istanza corrente ) non ha senso usarlo per i metodi o le variabili di classe CREAZIONE DI APPLICAZIONI 5 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. CREAZIONE DI APPLICAZIONI 6
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. CREAZIONE DI APPLICAZIONI 7 Passaggio di parametri ai metodi ffl I tipi primitivi sono passati per valore (by value). ffl Gli oggetti sono passati per indirizzo (by reference). ) sono modificati gli oggetti originali CREAZIONE DI APPLICAZIONI 8
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: [ 1345117] Number of Ones = 3 New values of the array: [ 0 3 4 5 0 0 7 ] CREAZIONE DI APPLICAZIONI 9 Metodi di classe I metodi di classe sono definiti mediante la parola chiave static. static int max (int arg1, int arg2) {... ffl sono utilizzabili anche in assenza di una istanza della classe ffl 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 CREAZIONE DI APPLICAZIONI 10
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 ffl Una classe costituisce il punto di partenza dell applicazione ffl La classe di partenza deve contenere il metodo main(), la cui segnatura è: public static void main (String arg[]) {... ffl Il metodo main è eseguito quando inizia l esecuzione dell applicazione main() è un metodo di classe ) la classe che lo contiene non è automaticamente istanziata CREAZIONE DI APPLICAZIONI 11 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" ffl I parametri sono memorizzati in un array di stringhe, che è passato come parametro al metodo main() dell applicazione. ffl 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. CREAZIONE DI APPLICAZIONI 12
Passaggio di parametri ad applicazioni ffl Esempio: class EchoArgs { public static void main(string args[]) { for (int i=0; i < args.length; i++) { System.out.println("Argument" + i + ": " + args[i]); ffl Al contrario del linguaggio C, args[0] contiene il primo parametro, non il nome del programma! ffl I parametri sono stringhe! ) per trattarli in modo diverso, bisogna convertirli CREAZIONE DI APPLICAZIONI 13 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: ffl mantenere una interfaccia più semplice verso altri oggetti (non sono definiti metodi diversi che facciano più o meno la stessa cosa) ffl 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! CREAZIONE DI APPLICAZIONI 14
import java.awt.point; class MyRect { int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; Un esempio di overloading void printrect(){ System.out.print("MyRect: <" + x1 + ", " + y1); System.out.println(", " + x2 + ", " + y2 + ">"); 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("----------"); CREAZIONE DI APPLICAZIONI 15 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 ffl inizializza le variabili dell oggetto ffl crea eventuali altri oggetti necessari ffl esegue tutte le operazioni necessarie alla vita dell oggetto Quando si crea una nuova istanza di un classe con una chiamata new,java ffl alloca la memoria necessaria per l oggetto ffl inizializza le variabili di istanza dell oggetto (al valore iniziale o di default) ffl 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 CREAZIONE DI APPLICAZIONI 16
I metodi costruttori: ffl hanno sempre lo stesso nome della classe ffl non hanno un valore di ritorno I metodi costruttori class Persona { String nome; int eta; Persona (String n, int a) { nome = n; eta = a; public static void main (String args[]) { Persona p; p = new Persona("Laura", 20); 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. CREAZIONE DI APPLICAZIONI 17 Metodi costruttori: esempio import java.awt.point; class MyRect2 { int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; 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; MyRect2(Point topleft, int w, int h) { x1 = topleft.x; y1 = topleft.y; x2 = (x1 + w); y2 = (y1 + h); void printrect(){ System.out.print("MyRect: <" + x1 + ", " + y1); System.out.println(", " + x2 + ", " + y2 + ">"); CREAZIONE DI APPLICAZIONI 18
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("----------"); CREAZIONE DI APPLICAZIONI 19 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 CREAZIONE DI APPLICAZIONI 20
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(); Xis0,Yis1,Zis3 I am an instance of the class PrintSubClass2 CREAZIONE DI APPLICAZIONI 21 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 Xis0 Yis1 Zis3 CREAZIONE DI APPLICAZIONI 22
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; CREAZIONE DI APPLICAZIONI 23 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. CREAZIONE DI APPLICAZIONI 24