ppt - DISI

annuncio pubblicitario
Overloading
Differenze nei vari
linguaggi
di
Elisa Trifirò e Barbara Tacchino
Argomenti trattati





Overloading: un tipo di Polimorfismo
Overloading in Java
Overloading in C++
Overloading in C#
Conclusioni
Classificazione di
Cardelli-Wegner

La classificazione più completa
risale al 1985 ed è opera di Luca
Cardelli e Peter Wegner:
Polimorfismo universale



Sono quelle funzioni che possono operare su
più tipi purché vengano rispettate alcune
proprietà.
Polimorfismo parametrico: programmazione
generica.
Polimorfismo per inclusione: programmazione
ad oggetti.
Polimorfismo parametrico



Idea: utilizzare un tipo come parametro
in una funzione generica.
E’ il compilatore che genera di volta in
volta l’implementazione corretta.
Esempio: template in C++
Polimorfismo per inclusione


Nell'approccio object-oriented si
definisce la classe degli elementi su cui
ha senso applicare una certa funzione.
Tutte le classi da essa derivate ne
erediteranno le funzioni, con la
possibilità di ridefinirle.
Polimorfismo ad-hoc



Nel polimorfismo ad-hoc rientrano:
Overloading
Coercion
Coercion


Coercion: quando un valore di un
tipo viene visto (e talvolta
trasformato) come valore di un
altro tipo.
Esempio: nel sommare un float e
un double, avviene una promozione
da float a double.
Overloading


Il termine overloading (da to
overload) significa sovraccaricamento
e overloading delle funzioni indica la
possibilità di attribuire allo stesso nome
di funzione più significati.
Esempio:
int x = 7 * 5;
double y = 3.1 * 7.4;
Overloading in Java

In Java é ammesso l’overloading nel
senso che é possibile definire più
versioni di un metodo o costruttore che
differiscono per la lista degli argomenti.
Esempio
class MyComplex{
double a;
double b;
double m (MyComplex p){return p.a;}
double m(double h){return this.a+h;}
}
Nota: non possono differire per il tipo di
ritorno.
Esempio

In Java non é ammesso l’overloading di
operatori.
class MyComplex{
double a,b;
public MyComplex add(MyComplex m){
this.a+=m.a;
this.b+=m.b
return new MyComplex(this.a,this.b);}}
Risoluzione dell’overloading in
Java


La risoluzione dell’overloading é la
scelta della versione da applicare ad
ogni chiamata di metodo.
In Java é fatta staticamente ossia al
momento della compilazione.
Algoritmo di risoluzione
dell’overloading in Java

1.
2.
3.
L’algoritmo di risoluzione é il seguente:
Si cercano tutte le versioni del metodo che
potrebbero essere applicate, cioè con il
nome giusto e con i tipi (statici)
Se si trovano più versioni applicabili, si
elimina via via ogni versione meno
“specifica” di un’altra
Se alla fine si arriva ad una sola versione, è
quella da applicare, altrimenti si ha un
errore statico
Considerazioni sulla risoluzione
dell’overloading in Java

La risoluzione dell’overloading in Java
corrisponde ad un preprocessing che
sostituisce al nome del metodo un
nome esteso con le opportune
informazioni di tipo.
Un esempio errato
public class B { public void unMetodo() {
System.out.println(“Glup!”);
}
public int unMetodo() {
System.out.println(“Glup!”); return 1; }
}
Questa classe dà errore in compilazione perché
non vi possono essere due metodi con lo
stesso nome e stessi parametri anche se con
tipi di ritorno differenti.
Dynamic binding in Java



A run-time viene considerato il tipo dinamico
del ricevitore della chiamata di metodo e da
quello avviene la ricerca gerarchica del
metodo da scegliere.
Non viene considerato il tipo dinamico dei
parametri.
Si continua ad andare in alto nella gerarchia
di classi finché non si arriva al primo
applicabile esattamente al tipo dinamico.
Esempio
class A { h(int i){return 0};
f(){return 1};
s(double d){return 2}; }
class B extends A { f(){return 3};
h(int i){return 4};
s(int i){return 5};}
class C extends A { f(){return 6}; }
A a1=new B();
A a2=new C();
B b=new B();
A a=new A();
Esempio
a.s(3.0); //2
a1.s(3.0); //2
b.s(0); //5
b.s(1.0); //2
((A) a1).h(4); //4
Overloading in C++

1.
2.
In C++ è permesso:
Due funzioni con lo stesso nome ma
parametri e tipi di ritorno differenti:
int media(int * array, int size);
double media(double a,double b);
Due parametri passati per riferimento che
differiscono per il qualificatore const sono
considerati differenti:
void f(int&);
void f(const int&);
Esempio

In C++ e’ permesso l’overloading di
operatori:
class MyComplex{
double a,b;
MyComplex operator +(const MyComplex
&obj) {
MyComplex temp;
temp.a=(*this).a+obj.a;
temp.b=(*this).b+obj.b;
return temp; } };
Implementazione
dell’overloading in C++


Ad ogni funzione del programma il
compilatore assegna un nome interno
che dipende dal nome della funzione e
dai suoi parametri.
Il meccanismo di risoluzione
dipende dal compilatore.
Risoluzione dell’overloading
in C++


Si passa attraverso un processo di
corrispondenza tra gli argomenti della
chiamata e i parametri della funzione.
Il compilatore confronta gli argomenti
della chiamata con le varie definizioni e
se possibile ne invoca una.
Algoritmo di risoluzione
dell’overloading in C++

1.
2.
La risoluzione avviene in tre passi:
Identificazione delle funzioni candidate
(funzioni che hanno lo stesso nome
della funzione chiamata)
Scelta delle funzioni utilizzabili
(funzioni i cui parametri corrispondono
agli argomenti della chiamata per
numero e tipo)
Algoritmo di risoluzione
dell’overloading in C++ 2
3.
Scelta della migliore funzione
utilizzabile ( funzione per cui gli
argomenti corrispondono come tipi
statici ai parametri)
Overloading in C#



Si possono dichiarare più metodi
con lo stesso nome ma parametri
diversi.
E’ permesso l’overloading di
operatori.
E’ permesso l’overloading con tipi di
ritorno diverso.
Esempio
class MyComplex {
double a,b;
public static operator +
(MyComplex a,MyComplex q) {
MyComplex z=new
MyComplex((p.a+q.a),(p.b+q.b));
return z;
}}

Overloading di operatori in C#
Gli operatori unari che possono essere
overloaded in C# sono :
+ - ! ~ ++ -- true false
 Gli operatori binari che possono essere
overloaded sono :
+ - * / % & | ^ <<
>> == != > < >= <=

Risoluzione dell’overloading in C#



L’insieme delle funzioni candidate è
ridotto a quelle funzioni applicabili
rispetto alla lista degli argomenti.
Se questo insieme è vuoto si ha un
errore in compilazione.
Altrimenti è scelta la migliore
possibile.
Risoluzione dell’Overloading in C#

L’algoritmo di risoluzione è simile a
quello utilizzato dal linguaggio Java.
Esempio
class A{…}
class B : A {…}
class C : B {…}
class D {
public static void
public static void
public static void
public static void
m(A
m(B
m(A
m(B
a){…}
b){…}
a, B b){…}
b, A a){…} }
Esempio (continuo)
A a=new A();
 C c=new C();
 D d=new D();
 d.m(a);/* D.m(A a) => d.m(A);*/
 d.m(c);/* D.m(A a), D.m(B b)=>d.m(B)
 D.m(c,c);/*D.m(A a,B b), D.m(B b, A a)
Error

Risoluzione degli operatori in C#

Le implementazioni degli operatori
definite dall’utente hanno la
precedenza su quelli predefiniti.
Overloading a run-time

A differenza di Java durante
l’esecuzione, viene ignorato il tipo
dinamico dell’oggetto che ha invocato il
metodo e viene quindi applicato quello
scelto a compile-time.
Linguaggio
overloading consentito
C++
costruttori, distruttori, funzioni, operatori (tutti
compresi ',' , 'new', 'delete' e '->')
conversioni implicite (cast)
Java
costruttori e funzioni
C#
costruttori, funzioni e operatori ad esclusione di:
'.', =, &&, ||, ?, : new e tutti gli operatori di
assegnazione composti come += *= perché vengono
sempre eseguiti con l'espansione delle operazioni
semplici (evitando i problemi in cui sia stato fatto
l'overloading degli operatori semplici e non di quelli
composti)
conversioni implicite (cast)
Conclusioni

L’overloading, se usato
correttamente, migliora la
leggibilità del codice evitando nomi
con ridondanza di informazioni.
Esempio


Volendo definire una funzione che
calcoli la potenza di interi e un’atra per i
float, potremmo chiamarle in due modi
diversi (es.IPow e FPow).
Questo però nasconde la similarità della
loro funzionalità.
Conclusioni



E’ difficile da gestire per il
compilatore.
Il dynamic binding causa un
rallentamento nell’esecuzione.
Il dynamic binding a run-time
potrebbe dare errori non segnalati
in compile-time.
Scarica