Programmazione Java: Variabili membro, Metodi La parola chiave final Romina Eramo [email protected] http://www.di.univaq.it/romina.eramo/tlp Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Roadmap › Definire una classe » Variabili membro » Metodi › La parola chiave final Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Definire una classe › Programmare in Java significa definire classi » oltre che creare oggetti da queste classi » e inviare messaggi a questi oggetti › Quando si definisce una classe è possibile includere due tipi di elementi (membri): » i campi, chiamati anche attributi o variabili membro o membri dati » i metodi, noti anche come funzioni membro › Una volta dichiarati i membri di una classe, è possibile accedere ad essi utilizzando il carattere “.”: <nome_oggetto>.<nome_membro> Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Definire una classe (2) › Quando progettiamo una classe, decidiamo quali metodi e quali campi essa contiene: » i campi e i metodi definiti in una classe saranno poi utilizzati dall’esterno della classe dal programmatore (con le debite limitazioni) › Questo modo di pensare al design di una classe come ad un processo di creazione di “elementi” visibili dal programmatore, ci porta a vedere i campi e i metodi di una classe come una interfaccia della classe: » cioè possiamo pensare all’oggetto come ad una scatola nera di cui noi vediamo solamente l’interfaccia » inoltre possiamo anche non interessarci a come tale interfaccia è stata implementata Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Progettare l’interfaccia › Quindi per definire una classe è opportuno prima pensare all’interfaccia della classe, cioè a cosa quella classe deve “mostrare” al mondo esterno: » Rectangle -> translate, rotate, ecc › E’ possibile definire dei metodi e delle variabili di una classe non visibili all’esterno e quindi utilizzabili solamente dall’interno della classe: » tali elementi non “faranno parte dell’interfaccia della classe” ma serviranno alla classe stessa per realizzare operazioni interne Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Proteggere l’accesso dei membri › Quando progettiamo una classe è necessario individuare ciò che sarà possibile utilizzare e cosa invece è solamente necessario al corretto funzionamento della classe: » nel secondo caso, diventa pericoloso permettere che altre classi possano modificare variabili o utilizzare funzioni pensate per lavorare sullo stato interno della classe stessa › Esistono perciò diversi tipi di elementi membro di una classe: » public, la cui visibilità è totale: le variabili così sono leggibili e modificabili e le funzioni sono invocabili da chiunque » private, la cui visibilità è ristretta alla classe proprietaria » protected, la cui visibilità è limitata alle classi derivate Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Variabili membro › Una volta “aperta” la definizione di una classe, è possibile dichiarare le variabili membro della classe › Tale dichiarazione avviene con una semplice istruzione di dichiarazione di variabile: public class Prova { public int a; private double b; Car auto; … } › In tale forma le variabili non sono inizializzate e sarà necessario farlo o nel costruttore oppure nel codice di qualche metodo, comunque prima che vengano utilizzate Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Variabili membro › Sintassi [modificatoriAccesso] [static|final|transient|volatile]* modificatoriAccesso = [ public | <tipo> <nome> private | protected ] › Non possono apparire più di una volta › Esempio » public static final String HELLO = “Hello”; Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Variabili membro › E’ possibile però utilizzare la forma di dichiarazione delle variabili con inizializzazione immediata: public class Prova { public int x=3; private double b=2.3; … } › Tale inizializzazione ha il risultato di inizializzare le variabili ai valori prescelti a tempo di costruzione, ossia come se tale inizializzazione fosse fatta nel costruttore Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Metodi › Sintassi [modificatoriAccesso] [ static | abstract | final | native | synchronized ]* tipoRitorno nomeMetodo(listaparametri) [ throws exceptions] modificatoriAccesso = [ public | private | protected ] › Non possono apparire più di una volta › Esempio public static final String getHello() { return “Hello World”; } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Metodi › Oltre alle variabili membro, è possibile specificare funzioni membro per una classe › La dichiarazione di una funzione membro è del tutto simile ad una dichiarazione di funzione normale: public void translate(int dx, int dy, Car C) › JAVA prevede di implementare la classe in fase di dichiarazione, quindi alla sintassi qui sopra seguirà immediatamente il blocco di implementazione: public void translate(int dx, int dy, Car C) { x=x+dx; y=y+dy; C.color=“white”; } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Metodi public class Rectangle { /** Variabili membro : coordinate del vertice alto a sx */ private int x; private int y; /** * Funzione membro : sposta il rect di dx e dy * @param dx * @param dy */ public void translate(int dx, int dy, Car C) { x = x + dx; y = y + dy; C.color = “white”; } } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final › Ha significati diversi a seconda del contesto, ma in generale dice: “Questo non può essere cambiato” › Può essere utilizzato in tre casi: » Dati » Metodi » Classi Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati › Modo per dire al compilatore che un dato è costante › Una costante è utile per due ragioni: » Può essere una costante nota in fase di compilazione che non cambierà mai › Il compilatore può scrivere direttamente il valore costante in qualsiasi calcolo dove esso è utilizzato » Può essere un valore inizializzato in fase di esecuzione che non si vuole cambiare Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati › Indica una variabile (di istanza o di classe) che può essere assegnata una sola volta ovvero costante › Una volta assegnata non può essere più modificata » Tipo reference non può essere modificato il riferimento » Valori all’interno dell’oggetto possono essere modificati › Java non fornisce un modo per rendere costante un oggetto arbitrario. Questa limitazione comprende anche gli array › Generalmente le costanti scritte in maiuscolo › Generalmente vengono utilizzate in congiunzione con parola chiave static › const parola chiave riservata ma non utilizzata Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class FinalData { private static Random rand = new Random(); private String id; public FinalData(String id) { this.id = id; } Entrambi possono essere // Can be compile-time constants: utilizzati come costanti in private final int VAL_ONE = 9; private static final int VAL_TWO = 99; fase di compilazione // Typical public constant: public static final int VAL_THREE = 39; // Cannot be compile-time constants: private final int i4 = rand.nextInt(20); static final int i5 = rand.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(22); private static final Value v3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { (vedere FinalData.java) return id + ": " + "i4 = " + i4 + ", i5 = " + i5; } Romina Eramo … Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class FinalData { private static Random rand = new Random(); private String id; public FinalData(String id) { this.id = id; } Modo tipico di definire // Can be compile-time constants: costanti, in questo modo è private final int VAL_ONE = 9; possibile utilizzarle anche private static final int VAL_TWO = 99; fuori dal package. Static per // Typical public constant: mettere in rilievo che ce n’è public static final int VAL_THREE = 39; una sola e final per dire che // Cannot be compile-time constants: è una costante private final int i4 = rand.nextInt(20); static final int i5 = rand.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(22); private static final Value v3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { (vedere FinalData.java) return id + ": " + "i4 = " + i4 + ", i5 = " + i5; } Romina Eramo … Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class FinalData { private static Random rand = new Random(); private String id; public FinalData(String id) { this.id = id; } // Can be compile-time constants: private final int VAL_ONE = 9; Il fatto di essere final non private static final int VAL_TWO = 99; significa essere noto in fase // Typical public constant: di compilazione public static final int VAL_THREE = 39; // Cannot be compile-time constants: Tale differenza si ha solo private final int i4 = rand.nextInt(20); static final int i5 = rand.nextInt(20); quando i valori vengono private Value v1 = new Value(11); inizializzati in fase di private final Value v2 = new Value(22); esecuzione private static final Value v3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { (vedere FinalData.java) return id + ": " + "i4 = " + i4 + ", i5 = " + i5; } Romina Eramo … Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class FinalData { private static Random rand = new Random(); private String id; public FinalData(String id) { this.id = id; } In questo caso emerge la // Can be compile-time constants: differenza tra final static e private final int VAL_ONE = 9; solo final private static final int VAL_TWO = 99; • il valore di i4 cambia per // Typical public constant: ogni istanza di FinalData public static final int VAL_THREE = 39; • Il valore di i5 rimane // Cannot be compile-time constants: sempre uguale a quello private final int i4 = rand.nextInt(20); dell’inizializzazione static final int i5 = rand.nextInt(20); avvenuta con la creazione private Value v1 = new Value(11); della prima istanza di private final Value v2 = new Value(22); private static final Value v3 = new Value(33); FinalData // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { (vedere FinalData.java) return id + ": " + "i4 = " + i4 + ", i5 = " + i5; } Romina Eramo … Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class FinalData { private static Random rand = new Random(); private String id; public FinalData(String id) { this.id = id; } // Can be compile-time constants: private final int VAL_ONE = 9; private static final int VAL_TWO = 99; // Typical public constant: public static final int VAL_THREE = 39; // Cannot be compile-time constants: private final int i4 = rand.nextInt(20); static final int i5 = rand.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(22); private static final Value v3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { return id + ": " + "i4 = " + i4 + ", i5 = " + i5; } Romina Eramo … Tecnologie dei Linguaggi di Programmazione v2 è final ma il suo valore (l’oggetto Value) può essere cambiato Non si può però cambiare il riferimento v2 ad un nuovo oggetto Stessa cosa anche per gli array (vedere FinalData.java) DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati › E’ possibile assegnare il valore della variabile NON contestualmente alla dichiarazione (blank final) › E’ necessario inizializzare le variabili final prima di poter essere utilizzato » Variabile di istanza › E’ necessario inizializzarla in tutti i costruttori oppure all’interno di un inizializzatore di istanza » Variabile di classe › E’ necessario inizializzarla all’interno di un inizializzatore statico › Un errore in fase di compilazione viene restituito in caso contrario Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati › I blank final forniscono molta più flessibilità nell’utilizzo » Ad esempio un campo final di una classe può così essere diverso per ciascun oggetto (Vedere BlankFinal.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati class Poppet { private int i; Poppet(int ii) { i = ii; } } public class BlankFinal { private final int i = 0; private final int j; private final Poppet p; // Initialized final // Blank final // Blank final reference // Blank finals MUST be initialized in the constructor: public BlankFinal() { j = 1; // Initialize blank final p = new Poppet(1); // Initialize blank final reference } public BlankFinal(int x) { j = x; // Initialize blank final p = new Poppet(x); // Initialize blank final reference } public static void main(String[] args) { new BlankFinal(); new BlankFinal(47); } } Romina Eramo Tecnologie dei Linguaggi di Programmazione (vedere BlankFinal.java) DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati public class Constants { public static void main(String[] args) { final double CM_PER_INCH = 2.54; System.out.println(“Centimetri per inch: ” + CM_PER_INCH); CM_PER_INCH = 10.30; //ERRORE IN COMPILAZIONE } //OPPURE public static final double CM_PER_INCH = 2.54; } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati class Point { int x,y; final Point root; static final Point ORIGIN; static { ORIGIN = new Point(0,0); } public Point(int x, int y ){ this.x = x; this.y = y; root = null; } public Point(int x, int y, Point root ){ this.x = x; this.y = y; this.root = root; } } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Dati class Test { public static void main(String[] args) { Point p1 = new Point(100,100); Point p2 = new Point(200,200,p1); p1.root = new Point(300,300); //ERRORE p2.root.x = 300; //OK System.out.println("ORIGIN.x:" + Point.ORIGIN.x); Point.ORIGIN = new Point(1000, 1000); //ERRORE Point.ORIGIN.x = 400; //OK } } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Argomenti › Java permette di rendere final gli argomenti dichiarandoli come tali nell’elenco degli argomenti › All’interno del metodo si può cambiare ciò a cui punta il riferimento all’argomento (vedere FinalArguments.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Argomenti class Gizmo { public void spin() {} } public class FinalArguments { void with(final Gizmo g) { //! g = new Gizmo(); // Illegal -- g is final } void without(Gizmo g) { g = new Gizmo(); // OK -- g not final g.spin(); } // void f(final int i) { i++; } // Can't change // You can only read from a final primitive: int g(final int i) { return i + 1; } public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } } Romina Eramo Tecnologie dei Linguaggi di Programmazione (vedere FinalArguments.java) DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Metodi › Un metodo può essere definito final: » Per evitare che una classe che eredita ne cambi il significato » Per ragioni di efficienza public class A { final void m1(){} void m2(){} } public class B extends A{ //! void m1() {} Illegal void m2() {} } Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Metodi › Tutti i metodi private di una classe sono implicitamente final » Poiché non si può accedere ad un metodo private, non si può ridefinirlo (Vedere FinalOverridingIllusion.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche La parola chiave final > Classi › Definendo una class final si stabilisce che non si vuole ereditare da quella classe o permettere a qualcun altro di farlo › I campi di una classe final possono essere o non essere final › Poiché con final si impedisce l’ereditarietà, tutti I metodi di una classe final sono implicitamente final, dato che non c’è modo di ridefinirli (Vedere Jurassic.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche