dispatch. overriding vs overloading notare che esistono due fasi nella selezione del metodo da...

24
Dispatch

Upload: antonino-pace

Post on 01-May-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Dispatch

Page 2: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Overriding vs overloading

• Notare che esistono due fasi nella selezione del metodo da invocare:

• Fase statica: risoluzione dell’overloading determina il tipo del metodo, in funzione del tipo

statico degli argomenti presenti nel messaggio

• Fase dinamica: dispatch determina il corpo del metodo, in funzione del tipo

dinamico del parametro implicito (ovvero, del destinatario del messaggio)

Page 3: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Polimorfismo – run time

• Dispatch articolato di quanto abbiamo visto …

• Metodi dispatch dinamico, con le seguenti eccezioni: metodi private, chiamate via super

• Metodi di classe (static) dispatch è sempre statico

• Campi dispatch è sempre statico, sia per variabili di istanza,

sia per variabili di classe (o static)

Continua…

Page 4: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Invocazione di metodi

• exp.m(a1,..., an) per definire precisamente l’effetto della chiamata

dobbiamo analizzare tre aspetti:

• selezione statica decide se è corretto invocare m(…) su exp, ovvero

se esiste un metodo da invocare determina il tipo del metodo da invocare

• dispatch determina il corpo del metodo da invocare

Page 5: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Selezione statica

exp.m(a1,..., an)

Due fasi:

1. Determina il tipo di exp

2. Determina la firma T m(T1,…Tn) del metodo da invocare in base al tipo degli argomenti a1,...,an

In questa fase (statica)

• tipo = tipo statico

Page 6: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Selezione Statica – Fase 1

exp.m(a1,..., an)

• Determina il tipo statico S di exp:1. exp = super:

• S è la superclasse della classe in cui l’invocazione occorre:

2. exp = this: • S è la classe in cui l’invocazione occorre

3. in tutti gli altri casi:• S è il tipo dichiarato per exp

Page 7: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Selezione statica – Fase 2

exp.m(a1,..., an) exp:S

• Determina la firma del metodo da invocare 1. calcola il tipo degli argomenti, a1:S1,.... an:Sn2. seleziona in S il metodo T m(T1,....,Tn) tale

che Si <:Ti e m() è accessibile dal contesto di chiamata

3. se S non ha un metodo m() con le caratteristiche desiderate, ripeti il passo 2 sul supertipo di S (ognuno dei supertipi di S ), finché non trovi un metodo oppure esaurisci la gerarchia.

Page 8: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Selezione statica e overloading

• L’algoritmo appena visto assume che ogni classe contenga al più una versione del metodo da invocare

• Che succede se esiste una classe contiene più di una versione?

• Che succede se una classe ed una superclasse contengono diverse versioni dello stesso metodo?

• Sono entrambi casi di overloading, e la selezione statica deve risolverlo

• Selezione statica richiede overloading resolution

Page 9: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Selezione statica – Fase 2 rivista

exp.m(a1,..., an) exp:S

• Determina la firma del metodo da invocare1. calcola il tipo degli argomenti, a1:S1,....

an:Sn

2. determina il best match T m(T1,...,Tn) per l’invocazione m(a1:S1,… an:Sn), a partire da S

• Se trovi una sola firma ok, altrimenti errore

Page 10: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Best Match

exp.m(a1:S1,..., an:Sn) exp:S

1. Determina l’insieme dei metodi applicabili

APP(S, m(S1, ..., Sn)) =

{U1.m(T11,...,T1n),...,Uk.m(Tk1,...,Tkn)}

tali che, per ogni j in [1..k] S <: Uj (quindi: esamina S ed i supertipi di S) m(Tj1, …. Tjn) è definito in Uj ed è visibile nel

punto della chiamata exp.m(a1,…,an). Si <: Tji per ogni i in [1..n]

2. Se l’insieme è vuoto fallisci

Page 11: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

3. Altrimenti, calcola l’insieme dei metodi migliori

BEST(S,m(a1:S1,…,. an:Sn))

rimuovi da APP(S, m(a1:S1, ... an:Sn)) ogni Up.m(Tp1, ..., Tpn) tale che esiste un metodo migliore, ovvero un metodo Uq.m(Tq1,...,Tqn) tale che - Uq <:Up (è definito in una superclasse più vicina a S) - Tqi <: Tpi (ha tipi degli argomenti piu vicini agli Si)

4. Se BEST(S,m(a1:S1,…,an:Sn)) contiene più di un metodo, fallisci.

Altrimenti l’unico metodo nell’insieme e` il best match per la chiamata exp.m(a1,...,an)

Best Match

Page 12: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

APP(A, m(int)) = { A.m(int) }

APP(B, m(String)) = { B.m(String) }

APP(B, m(int)) = { A.m(int) }

class A { public void m(int i) { System.out.println("A.m(int)"); }}class B extends A { public void m(String s) { System.out.println("B.m(String)"); }}class over { public static void main(String[] args) { B b = new B(); A a = new B(); a.m(1) b.m(“a string”) ; b.m(1); }}

Best Match – Esempi

// APP(A,m(int)) = {A.m(int)}// APP(B,m(String))= {B.m(String)}// APP(B,m(int)) = {A.m(int)}

Page 13: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Best Match – Esempi

APP(A, m(int)) = { A.m(int) }

APP(B, m(String)) = { B.m(String) }

APP(A, m(String)) = { }

class A { public void m(int i) { System.out.println("A.m(int)"); }}class B extends A { public void m(String s) { System.out.println("B.m(String)"); }}class over { public static void main(String[] args) { B b = new B(); A a = new B(); a.m(1) b.m(“a string”) ; a = b; a.m(“a string”); }}

// APP(A,m(int)) = {A.m(int)}// APP(B,m(String))= {B.m(String)}

// APP(A,m(string))= {}

Page 14: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Best Match – Esempiclass A {

public void m(int i) { System.out.println("A.m(int)"); }

}

class B extends A {

public void m(double f) { System.out.println("B.m"); }

}class over { public static void main(String[] args) { B b = new B(); A a = new B(); a.m(1); b.m(1.5); b.m(1); }}

// APP(A,m(int)) = {A.m(int)}// APP(B,m(double))= {B.m(double)}// APP(B,m(int)) = {A.m(int),B.m(double)}// BEST(B.m(int)) = {A.m(int),B.m(double)}

Page 15: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Best Match – Esempiclass A {

public void m(double g) { System.out.println("A.m"); }

}

class B extends A {

public void m(int i) { System.out.println("B.m"); }

}class over { public static void main(String[] args) { B b = new B(); A a = new B(); a.m(1); b.m(1.5); b.m(1); }}

// APP(A,m(int)) = {A.m(double)}// APP(B,m(double))= {A.m(double)}// APP(B,m(int)) = {A.m(double),B.m(int)}// BEST(B.m(int)) = {B.m(int)}

Page 16: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Best Match – Esempi

class A {

public void m(int i, float f) { /* just return */}

public void m(float f, int i) { /* just return */}

}

class test {

public static void main(String[] args) {

A a = new A();

a.m(1, 1);

}

// APP(A, m(int,int)) = { A.m(int,float), A.m(float,int) }

// BEST(A,m(int,int)) = { A.m(int,float), A.m(float,int) }

Page 17: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Invocazione di metodi

exp.m(a1,..., an) per definire precisamente l’effetto della chiamata dobbiamo

analizzare tre aspetti:

• selezione statica: determina la firma del metodo da invocare calcolo del best match

• dispatch dinamico: determina il corpo del metodo da invocare se il dispatch è statico esegui il corpo del metodo determinato

dalla selezione statica altrimenti esegui il corpo del metodo con il tipo determinato

dalla selezione statica che trovi a partire dal tipo dinamico di exp

Page 18: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Esempio class A {

public void m(double d){System.out.println("A.m(double)");

public void m(int i) { System.out.println(“A.m(int)"); }

}

class B extends A {

public void m(double d){System.out.print(“B.m(double)”); }

}

class over {

public static void main(String[] args) {

{ A a = new B(); a.m(1.5); }

}

// Selezione statica: BEST(A, m(double)) = { A.m(double) }

// Dispatch: B ridefinisce m(double). Quindi esegui B.m(double)

Page 19: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Esempio class A {

public void m(double d){ System.out.println("A.m(double)");

public void m(int i) { System.out.println(“A.m(int)"); }

}

class B extends A {

public void m(double d){System.out.print(“B.m(double)”); }

}

class over {

public static void main(String[] args) {

{ A a = new B(); a.m(1); }

}// Selezione statica: BEST(A, m(int)) = { A.m(int) }

// Dispatch: B non ridefinisce m(int). Quindi esegui A.m(int)

Page 20: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Esempio

class A {

public void m(double d){ System.out.println("A.m(double)");

public void m(int i) { System.out.println(“A.m(int)"); }

}

class B extends A {

public void m(double d){System.out.print(“B.m(double)”); }

}

class over {

public static void main(String[] args) {

{ B b = new B(); b.m(1); }

}// Selezione statica: BEST(A, m(int))={A.m(int),B.m(double)}

Page 21: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Metodi private : dispatch statico

• Essendo private , non sono accessibili alle sottoclassi.

• Quindi le sottoclassi non possono fare overriding di questi metodi

• Dispatch può essere deciso dal compilatore

Continua…

Page 22: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Metodi private : dispatch statico

class A { public String test() { return this.sd() + " , " + this.dd(); } private String sd(){ return "A.sd()"; } public String dd() { return "A.dd()"; }}

class B extends A { public String sd() { return "B.sd()"; } public String dd() { return "B.dd()"; }}. . . // new B().test() = “A.sd(), B.dd()”// new A().test() = “A.sd(), A.dd()”

dispatch statico: A.sd()

dispatch dinamico: risolto a run time

Page 23: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Chiamate via super: dispatch statico

class A { public String test() { return dd(); } public String dd() { return "A.dd()"; }}

class B extends A { public String dd(){ return (super.dd() + " , " + "B.dd()"); }}. . . // super.dd() invoca sempre A.dd()// new B().test() = “A.dd(), B.dd()”// new A().test() = “A.dd()”

Page 24: Dispatch. Overriding vs overloading Notare che esistono due fasi nella selezione del metodo da invocare: Fase statica: risoluzione delloverloading determina

Campi: dispatch staticoclass C { String str = "C"; public void m() { System.out.println(str); }}class D extends C { String str = "D"; public void n() { System.out.println(str); }}

. . . D d = new D(); d.m(); // Cd.n(); // D System.out.println(d.str); // DC c = d;

c.m(); // C

((D)c).n(); // D

System.out.println(c.str); // C