Programmazione Java: Variabili membro, Metodi La parola chiave

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