Upload
vuongnhan
View
218
Download
0
Embed Size (px)
Citation preview
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
1
Corso di Laurea in Informatica
Università degli Studi di Salerno
6. Java: Ereditarietà
Vittorio Scarano
Algoritmi e Strutture Dati: Sistemi Distribuiti
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
2
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
2
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
3
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
4
Spazio di indirizzamento (Namespace)
• Non esistono variabili globali– ogni campo e metodo sono all'interno di classi
– Ogni classe è all'interno di un package
• I package hanno un nome univoco – david.games.tetris.SoundEffect.play()
Java è costruito per il caricamento dinamico delle classi, anche da rete
Il problema dell' indirizzamento è trattato con cura
Package name Classe Metodo
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
3
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
5
I package
• Servono per raggruppare classi Java
• La libreria Java è distribuita in package– java.util, java.lang, etc.
• Organizzazione gerarchica:– tutto la libreria sotto java.* e javax.*
• Non necessario strettamente per programmi piccoli:– ma utile al crescere della dimensione del programma
– e, conseguentemente, al crescere del numero di classi
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
6
Motivazioni per i package
• Organizzazione di programmi in unità
• Permettono di fornire un nome unico per le classi:• basato spesso sul dominio Internet, scritto in ordine inverso
• ad esempio: com.horstmann.corejava.example
• Permettono una ulteriore protezione di visibilità– una classe può accedere a tutte le classi del suo package e a
tutte le classi public degli altri package
• Servono per identificare le classi
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
4
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
7
Uso dei package
• Accesso:– inserimento del nome completo
– uso della istruzione import
• Istruzione import:– non è possibile usarla così
• import java.*.* • import java.l*
java.util.Date oggi = new java.util.Date();
import java.util.*;……Date oggi = new Date();
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
8
Attenzione: import non è include
• include– direttiva al preprocessore di inserire i file indicati all’interno
del sorgente
– tipicamente usata per utilizzare file headerdi interfaccia per libreria
– non “eliminabile” dall’uso quotidiano
• import– semplificazione nella specifica del nome delle classi
– di fatto, possibile non usarla
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
5
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
9
Classi in un package
• Prima del codice inserire:
• Se non si indica alcun package:– i file fanno parte del package di default
• Associazione tra namespace e filesystem– i file del package vanno inseriti in una sottodirectory
corrispondente al nome completo del package
– esempio: com/horstmann/corejava è la directory del package com.horstmann.corejava
package com.horstmann.corejava;
class Qualsiasi {……
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
10
Un esempio: la classe PackageTest
import com.horstmann.corejava.*;
public class PackageTest {public static void main (String [ ] args) {
Employee impieg ;impieg=new Employee (“Gianni”, 30000,
1987, 12, 10); impieg.raiseSalary(5);System.out.println (
“Nome:”+ impieg.getName() +“ Salario:” + impieg.getSalary() +“ Assunto:”+ impieg.getHireDay() );
}}}
• Importa un package– di cui usa la classe
Employee
• Istanza di Employee
• Aumento stipendio
• Stampa
PackageTest.java
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
6
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
11
Un esempio: la classe Employee
package com.horstmann.corejava;import java.util.*;
public class Employee {….….
// campi delle istanze della classeprivate String name;private double salary;private Date hireDay;
}
• Appartenenza ad un package
• Importa un package
• Filesystem:• PackageTest.java• PackageTest.class• com\
• horstmann\• corejava\
• Employee.java• Employee.class
Employee.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
12
Localizzazione delle classi
• Di solito, preferibile non fare riferimento alla directory corrente
• Possibile selezionare directory che servono da punto di partenza per cercare le classi (per javac e java)– percorso delle classi (CLASSPATH)
• Variabile di ambiente:– CLASSPATH=.;C:\classes;D:\classes
• Su linea di comando di javac e java– javac -classpath C:\classes ProgramJava.java
• Possibile inserire le classi in un archivio (JAR)
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
7
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
13
Visibilità: l’uso dei package
• Tra le visibilità: – public (accessibile a tutte le classi)
– private (accessibile solamente alla classe)
• ..esiste l’ambito di package:– quando una classe, un metodo, una variabile non sono
cotrassegnate né public né private allora
– risultano visibili da tutte le classi dello stesso package
• Attenzione:– mentre per i metodi questa strategia risulta accettabile
– … per i campi va contro l’incapsulamento dei dati
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
14
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
8
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
15
La documentazione
• Specialmente nella programmazione orientata ad oggetti, la documentazione è fondamentale– la suddivisione del programma in classi rende di difficile
consultazione la documentazione per i numerosissimi metodi delle numerosi classi di cui si compone un programma
• Javadoc– crea automaticamente documentazione
– … se inserita dal programmatore con commenti particolari (/** … */)
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
16
Documentazione in Javadoc
package com.horstmann.corejava;import java.util.*;/**
Questa classe rappresenta un esempio di una classe appartenente ad un package.La classe definisce oggetti Impiegato che hanno nome, salario e datadi assunzione come dati. Vengono forniti dei semplici metodi per illoro trattamento.@author Vittorio Scarano@version 3.2.5
*/public class Employee{….
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
9
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
17
Documentazione in Javadoc (2)
…public class Employee{
/**Metodo costruttore inserito (con tutti i parametri). Da notare che iparametri passati per la data di assunzione sono anno, mese e giorno, ma chequesti vengono rappresentati in maniera diversa all'interno del programma.@param n (String) il nome dell'impiegato@param s (double) il salario di inizio@param year (int) l'anno di assunzione@param month (int) il mese di assunzione@param day (int) il giorno di assunzione*/public Employee(String n, double s,
int year, int month, int day){….
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
18
Documentazione in Javadoc (3)
/**Metodo per accedere al campo nome dell'oggetto@return restituisce il nome (String)*/public String getName(){
return name;}/**Metodo per accedere al campo salario dell'oggetto@return restituisce il salario (double)*/public double getSalary(){
return salary;}
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
10
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
19
Documentazione in Javadoc (4)
/**Metodo per accedere alle informazioni sulla data di assunzione@return restituisce la data di assunzione (Date)
*/public Date getHireDay(){
return hireDay;}/**
Metodo per aumentare il salario dell'impiegato. Viene passatala percentuale di aumento e il salario risulta aumentato@param byPercent (double) percentuale di aumento
*/public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;salary += raise;
}
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
20
Documentazione in Javadoc (5)
/ **Campo nome dell'impiegato
*/private String name;/**
Campo salario dell'impiegato*/private double salary;/**
Campo data di assunzione dell'impiegato*/private Date hireDay;
}
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
11
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
21
Alcuni suggerimenti
• Mantenere sempre, sempre, semprei dati privati
• Inizializzare i dati
• Se una classe contiene troppi campi di dati primitivi, forse è il caso di creare un’altra classe
• Creare con criterio i metodi di modifica dei campi
• Suddividere le classi “troppo” grandi
• Utilizzare la documentazione del codice sin dall’inizio della scrittura dei programmi
• Utilizzare le convenzioni per nomi di classi, di variabili, di metodi etc.
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
22
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
12
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
23
L’esempio della classe Employee
import java.util.*; // per Date e Calendarpublic class Employee {
public Employee (String n, double s, int year, int month, int day)
{ name = n;salary = s;GregorianCalendar cal =new GregorianCalendar(year,
month-1, day);hireDay = cal.getTime();
}// …………………..Uno dei metodi di accesso
public String getName () { return name;}private String name;private double salary;private Date hireDay;
}
• Il costruttore– stesso nome della classe– assegna i campi
dell’oggetto che costruisce
• Un metodo di accesso– restituisce il nome
• Campi della istanza– una stringa (Nome)– un double (salario)– data di assunzione– tutti campi privati
Employee.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
24
Definizione di una classe EmployeeTest
import java.util.*; public class EmployeeTest {public static void main (String [ ] args) {
Employee[ ] staff = new Employee [ 3 ] ;staff [0]=new Employee (“Gianni”, 30000,
1987, 12, 10); staff [1]=new Employee (“Giorgio”, 35000,
1985, 10, 31); staff [2]=new Employee (“Ugo”, 28000,
2000, 1, 1); for (int i=0; i< staff.length; i++)
System.out.println (“Nome:”+ staff[i].getName() +“ Salario:” + staff[i].getSalary() +“ Assunto:”+ staff[i].getHireDay() );
}
}
• Dichiarazione di array di Employee
• Assegnazione:– uso del costruttore
• Stampa dei dati inseriti– uso di metodi getSalary() e
getHireDay() definiti in maniera simile a getName()
EmployeeTest.java
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
13
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
25
Una descrizione in UML
«constructor»+Employee(n: String, s:double, year: int,
month: int, day: int)«misc»+ getName() : String+ getSalary() : double+ getHireDay() : Date+ raiseSalary(perCent double)
- name : String- salary : double- hireDay : Date
Employee
«misc»+ main (String [ ] args)
EmployeeTest
Nome della classe
Variabili delle istanze
Metodi delle istanze
Modificatori di accesso
- = privato+ = pubblico
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
26
Una classe Manager
• Si vuole aggiungere un manager alla gerarchia di classi
• il Manager ha:– un nome
– una data di assunzione
– un salario
– un bonus che gli viene dato al raggiungimento di obiettivi
• A parte bonusrichiede gli stessi campi e metodi di Employee
– possiamo far ereditare tutto da Employee
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
14
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
27
La classe Manager
public class Manager extends Employee {public Manager (String n, double s,
int year, int month, int day){ super (n, s, year, month, day);
bonus = 0;}
// ……………………………..…Metodi acc./mod. public double getBonus () { return bonus;}public void setBonus(double b){ bonus = b; }
// …………………………….…Metodo override public double getSalary(){ double bs=super.getSalary();
return bs+bonus;}
// …………………………………Variabili istanza private double bonus;
}
• Il costruttore– richiama il costruttore
della superclasse– assegna il valore del
campo bonus
• Accesso/Modifica– restituisce il bonus– assegna il bonus
• Metodo che fa override– il salario è la somma del
salario da impiegato e il bonus
• Variabile istanza
Manager.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
28
Alcune considerazioni sul salario
• Queste soluzioni non funzionano per getSalary()
– salary si riferisce alla variabile di Employee che non risulta accessibile (in quanto private)
– getSalary() si riferisce al metodo della classe Manager (che è lo stesso in cui si trova la chiamata!)
public double getSalary(){ return salary+bonus;}
public double getSalary(){ double bs=getSalary();
return salary+bonus;}
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
15
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
29
Definizione di una classe ManagerTest
import java.util.*; public class ManagerTest {public static void main (String [ ] args) {
Manager boss = new Manager(“Bruce”,80000, 1987, 10, 23);
boss.setBonus(5000); Employee[ ] staff = new Employee [ 3 ] ;staff [0]=boss; staff [1]=new Employee (“Giorgio”, 35000,
1985, 10, 31); staff [2]=new Employee (“Ugo”, 28000,
2000, 1, 1); for (int i=0; i< staff.length; i++)
System.out.println (“Nome:”+ staff[i].getName() +“ Salario:” + staff[i].getSalary() +“ Assunto:”+ staff[i].getHireDay() );
}}
• Oggetto boss– si setta il bonus
• Dichiarazione di array di Employee
• Assegnazione:– il primo impiegato è il boss
• Stampa dei dati inseriti– per il boss si chiama il
metodo getSalary() e quindi somma anche il bonus
ManagerTest.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
30
Polimorfismo
• La caratteristica che un oggetto può fare riferimento a più tipi reali.
• Qualsiasi oggetto della sottoclasse è anche un oggetto della superclasse
extends
«constructor»+Employee(n: String, s:double, year: int,
month: int, day: int)«misc»+ getName() : String+ getSalary() : double+ getHireDay() : Date
- name : String- salary : double- hireDay : Date
Employee
«constructor»+Manager(n: String, s:double, year: int,
month: int, day: int)«misc»+ getBonus() : double+ setBonus(b:double) : void+ getSalary() : double
- bonus : double
Manageroverride
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
16
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
31
Principio di sostituzione
• E’ possibile utilizzare un oggetto della sottoclasse ogni volta che il programma si aspetta un oggetto della superclasse
• Variabili polimorfiche:
• Attenzione: non è possibile il contrario!
Employee e;e = new Employee(…);e = new Manager(…); // Ok, funziona
Employee[ ] staff = new Employee[3];Manager boss = new Manager(…);staff[0] = boss;
Manager m = staff[i]; // NON funziona!
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
32
Binding dinamico (1)
• Passi effettuati quando viene applicata la chiamata di un metodo ad un oggetto:– 1. il compilatore controlla il tipo di oggetto ed il nome del
metodo• conta tutti i possibili metodi candidati (firma di un metodo)
– 2. il compilatore determina i tipi di parametri• risoluzione dell’overloading
– 3. se il metodo è static, private, final o un costruttore, allora il compilatore sa che metodo deve essere chiamato
• binding statico (più efficiente)
altrimenti si usa il binding dinamico a run-time
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
17
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
33
Binding dinamico (2)
– 4. la macchina virtuale a run-time, deve chiamare il metodo adatto al tipo reale dei parametri
• se il tipo del parametro è di una classe D, sottoclasse di C,….– si cerca il metodo in D, se non lo si trova si cerca nella superclasse C…
• Per ottimizzare il tempo:– la macchina virtuale precalcola una tabella di metodi
• con tutte le firme ed i corrispondenti metodi da chiamare
• Il binding dinamico permette la estensibilità senza ricompilare il codice
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
34
Disabilitazione della ereditarietà
• E’ possibile evitare che una classe possa essere usata come superclasse di una sottoclasse
– la classe Executive non potrà servire da superclasse
• E’ anche possibile evitare l’overriding di un metodo:
• Motivi:– efficienza (uso del binding statico)
– sicurezza (comportamento fissato e non modificabile)
final class Executive extends Manager {..
public final String getName() {..
}
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
18
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
35
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
36
Cast (conversione di tipo)
• La conversione di tipo permette di convertire anche un riferimento ad un oggetto di una classe a un’altra.– ripristina la capacità di un oggetto dopo che il suo tipo era
stato temporaneamente “dimenticato”
– non è possibile “mentire”…
Manager boss = new Manager(“Bruce”,80000, 1987, 10, 23);Employee[ ] staff = new Employee [ 3 ] ;staff [0]=boss; staff [1]=new Employee (“Giorgio”, 35000, 1985, 10, 31);….Manager newboss = (Manager) staff[0]; // OK casting
Manager newboss = (Manager) staff[1]; // errore a run-time
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
19
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
37
Casting guidato dalla conoscenza della classe• Come si può fare per sapere la classe di un oggetto?
– l’operatore istanceof permette di controllare la appartenenza di un oggetto ad una classe
Manager boss = new Manager(“Bruce”,80000, 1987, 10, 23);Employee[ ] staff = new Employee [ 3 ] ;staff [0]=boss; staff [1]=new Employee (“Giorgio”, 35000, 1985, 10, 31);….for (int i=0; i< staff.length; i++)
if (staff[i] istanceof Manager) Manager newboss = (Manager) staff[i];
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
38
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
20
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
39
Classi astratte
• Utilizzando la gerarchia di ereditarietà, si possono identificare classi che:– rappresentano una struttura portante per tutte le altre classi
– non risulta mai istanziata ma figura solamente come superclasse nella gerarchia
• Una classe astratta può contenere:– metodi astratti (da implementare a cura delle sottoclassi)
– metodi non astratti
– variabili istanza (non astratte)
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
40
Un esempio di uso di classi astratte
• Nella gerarchia della classe Employee e Manager, potremmo definire Person come una superclasse di Employee
• Da Person potremmo poi derivare Student
• A questo punto la classe Person può essere progettata come astratta
Manager Employee
Person
Student
Classe astratta in corsivo
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
21
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
41
Definizione della classe Person
public abstract class Person {
public Person (String n) {name = n;
}
public abstract String getDescription();
public String getName () {return name;
}
private String name;}
• Classe astratta
• Costruttore– metodo concreto
• Metodo astratto– dovrà essere
implementato dalle sottoclassi
• Metodo concreto
• Variabile istanza
Person.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
42
Definizione della classe Employee
import java.text.*;public class Employee extends Person {
public Employee (String n, double s) {super (n);salary = s;
}public double getSalary() {
return salary;}
public String getDescription() {NumberFormat formatter =NumberFormat.getCurrencyInstance();
return “Impiegato con salario”+formatter.format(salary);
} private double salary;
}
• Estende Person
• Costruttore– chiama il costruttore di
Person passando il nome
• Un metodo proprio
• Implementazione del metodo astratto di Person
– formattazione in valuta corrente
– restituzione descrizione
• Variabile istanza
Employee.java
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
22
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
43
Definizione della classe Student
public class Student extends Person {
public Student (String n, String c) {super (n);corsoLaurea = c;
}public String getCorsoLaurea() {
return corsoLaurea;}
public String getDescription() {return “Studente in ”+ corsoLaurea;
}
private String corsoLaurea;}
• Estende Person
• Costruttore– chiama il costruttore di
Person passando il nome
• Un metodo proprio
• Implementazione del metodo astratto di Person
• Variabile istanza
Student.java
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
44
Definizione della classe PersonTest
public class PersonTest {
public static void main (String[ ] args) {Person[ ] p = new Person [2];p[0]=new Employee (“Pippo”, 50000);p[1]=new Student (“Pluto”,
“Informatica”);
for (int i = 0; i < p.length; i++) System.out.println(p[i].getName()+
”,”+ p[i].getDescription());}
}
• Serve come esempio
• Alloca un array di 2 Person– una è Employee
– l’altra è Student
• Vengono stampati:– chiamando getName()
• metodo ereditato dalla classe Person
– chiamando getDescription()
• metodo astratto di Personimplementato nelle rispettive classi
PersonTest.java
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
23
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
45
Il diagramma delle classi in UML dell’esempio
«constructor»+Employee(n: String, s:double)«misc»+ getSalary() : double
- salary : double
Employee
«constructor»+Person(n: String)«misc»+ getName() : String+ getDescription() : String
- name : String
Person
«constructor»+Student(n: String, c: String)«misc»+ getCorsoLaurea() : String
- corsoLaurea : String
Student
Metodi astratti in corsivo
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
46
Accesso protetto alla superclasse
• Metodi e variabili dichiarate private non sono visibili dalle altre classi– compreso le sottoclassi
• Dichiarando protected un campo/metodo si permette l’accesso alle sottoclassi
• Modificatori di accesso in Java– private: visibile solamente dalla classe di appartenenza
– <nessuna keyword>: visibile solo dal package
– protected: visibile solo dal package e dalle sottoclassi
– public: visibile da tutte le classi
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
24
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
47
Organizzazione della lezione
• Il namespacedi Java: i package• Supporto alla documentazione: JavaDoc• Ereditarietà
– Polimorfismo– Binding dinamico
• Casting e conversioni di tipo• Classi astratte• Interfacce
– motivazioni, modalità di uso e proprietà
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
48
Le interfacce
• Descrivono quello che una classe deve fare senza specificare come deve farlo
• Una interfaccia non è una classe
• E’ una serie di richieste– a cui la classe che si conforma alla interfaccia deve poter
rispondere
• Il concetto di “contratto di un fornitore di servizi”– “Se la tua classe è conforme alle specifiche di una
particolare interfaccia allora io eseguirò il servizio richiesto”
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
25
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
49
Un esempio: il metodo sort di Arrays
• Il metodo sort della classe Arrays offre un contratto:– “Se la tua classe è conforme alle specifiche della interface
Comparable allora io eseguirò il servizio di ordinare unarray di oggetti di quella classe”
• La interface Comparable:– un solo metodo
• La chiamata x.compareTo (y)
– prende un Object e restituisce un intero• negativo se x < y, positivo se x > y, 0 se x = y
public interface Comparable {int compareTo (Object other);
}
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
50
La classe Employee
• Facciamo in modo che la classe Employee possa usufruire del servizio offerto da sort di Arrays
• Il contratto:– innanzitutto la classe deve essere conforme alla interface
Comparable
– poi deve implementare il metodo che ha “promesso” di offrire:
class Employee implements Comparable {…
}
class Employee implements Comparable {public int compareTo (Object otherObj) {
Employee other=(Employee) otherObj;if (salary < other.salary) return -1;if (salary > other.salary) return 1;return 0;
}….
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
26
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
51
Le interfacce e il type-check in compilazione
Perché Employee non può offrire direttamente (silenziosamente!) il metodo compareTo()?
• Risposta: Java è fortemente tipizzato– il compilatore deve poter controllare a tempo di
compilazione la correttezza di istruzioni del metodo sort di arrays (cha sta ordinando un array di Object a[ ]) del tipo:
– se il compilatore ha il mezzo di controllare che la classe a cui realmente appartiene a[ ] implementa Comparable può essere sicura che il metodo ci sarà.
if (a[i].compareTo(a[j]) > 0) {…. // metti al posto giusto a[i] e a[j]
}
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
52
Interface: differenza con la ereditarietà
• Sembrano molto simili alla ereditarietà
• Servono (al linguaggio Java) per implementare la ereditarietà multipla:– in C++ e Smalltalk, una classe può ereditare da più di una
classe (meccanismo comunque poco usato)
– seppur potente come meccanismo, rende complesso la identificazione del metodo da eseguire
– caratteristica eliminata in Java
– possibile usare le interface per cui è possibile la ereditarietà multipla
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
27
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
53
Perché il Dynamic Dispatchingè efficiente in Java
• Ogni classe:• può avere solo una
superclasse (extends)• ma può implementare
diverse interface• I metodi delle interface
• sono comunque implementati nella classe
• La ricerca avviene in maniera lineare bottom-up
Classe T
Classe S
Classe Q
Classe Z
Interface I4 Interface I3
Interface I2
Interface I1
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
54
Proprietà delle interfacce (1)
• Le interfacce non sono classi– è un errore
• E’ possibile però dichiarare una variabile di interfaccia:
– che farà riferimento ad un oggetto di una classe che implementa la interfaccia e quindi è corretto:
• Si può controllare se un oggetto implementa una interfaccia:
x = new Comparable(..); //Errore
Comparable y; // Ok
y = new Employee (…); // Ok
if (z istanceof Comparable) …
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
28
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
55
Proprietà delle interfacce (2)
• Le interfacce:– non contengono variabili di istanza
– non contengono definizioni di metodi
– possono contenere costanti
• Possono essere derivate:– derivare una interfaccia da una altra interfaccia attraverso la
keyword extends
• Una classe può implementare più interfacceclass Employee implements Comparable, Cloneable {….
public interface Powered extends Moveable {…
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
56
Interfacce e callback (1)
• Il meccanismo di callback:– si specifica la azione che deve accadere ogni qualvolta un
evento accade
• Alcuni eventi:• tasto premuto• click del mouse• voce del menù selezionato
• Esempio:– nella classe javax.swing c’è una classe Timer che può
avvisare del trascorrere del tempo• si costruisce il Timer e lo si informa della azione da compiere
quando è trascorso un certo intervallo di tempo
ASD: Sistemi Distribuiti (Prof. Scarano) 24/04/2002
29
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
57
Interfacce e callback (2)
• Come si può informare Timer di cosa fare?– si passa a Timer un oggetto i cui metodi devono essere
chiamati quando c’è qualcosa da fare
• Il contratto offerto da Timer:– “Se la tua classe è conforme alle specifiche della interface
ActionListener di java.awt.event allora io eseguirò il servizio di chiamare il metodo actionPerformed quando il tempo sarà trascorso”
public interface ActionListener {void actionPerformed (ActionEvent event);
}
AS
D: S
iste
mi D
istr
ibui
ti.
Vi.t
tori
o S
cara
no
58
Un esempio di callback: il segnale orario
• Vogliamo un messaggio che “al beep sono le ore..”– seguito da un beep ogni 10 secondi
• Usiamo poi TimePrinter():– settando il tempo a 10000 millisecondi
class TimePrinter implements ActionListener {public void actionPerformed (ActionEvent event) {
Date now = new Date();System.out.println (“al beep sono le ore ”+now);Toolkit.getDefaultToolkit().beep();
}}
ActionListener lis = new TimePrinter ();Timer t = new Timer (10000, lis);…t.start();