Le polymorphisme est souvent limité au seul contexte des hiérarchies de classes (sous-typage). Mais savez-vous qu'il en existe d'autres formes et que, historiquement, son utilisation en programmation objet est la plus récente de toutes?
Au cours de ce talk, nous tenterons de définir ce qu'est le polymorphisme pour ensuite découvrir combien ce concept est... polymorphe!
1. Polymorphisme : un concept
polymorphe!
Human Talks Montpellier - 18 nov. 2014
Aurélien Regat-Barrel
2. Polymorphisme et sous-typage
Le polymorphisme est souvent restreint au seul
mécanisme de méthode virtuelle en POO :
● Utilisé pour abstraire le comportement des classes
● Implique une hiérarchie de classes (sous-typage)
● Concepts liés : héritage, typage dynamique, vtable
Mais il en existe d'autres formes !
3. Polymorphisme ?
Mais au fait, c'est quoi le polymorphisme ?
Mot d'origine grecque voulant dire :
« qui peut prendre plusieurs formes »
● Capacité d'une expression à être valide avec plusieurs types
● Entité (symbole) capable d'agir sur des valeurs de différents types
● Fait de considérer qu'une variable ou valeur peut être de plusieurs
types possibles
● ...
4. Exemples ?
Commande shell valide sur différents types de fichiers
Commandes du presse papier (CTRL-C, CTRL-V)
Compatibilité ascendante :
● Binaire : versions de dll, kernel, interpréteur...
● API : POSIX, Win32
Commandes HTTP valides sur un serveur Apache / IIS…
5. Un peu d'histoire...
1967 Christopher Strachey – un des tout
premiers programmeurs - distingue
plusieurs formes de polymorphisme.
La même année : Simula 67,
premier langage à introduire
le concept de classe !
Begin
Class Glyph;
Virtual: Procedure print Is Procedure print;
Begin
End;
Glyph Class Char (c);
Character c;
Begin
Procedure print;
OutChar(c);
End;
6. Première classification (1967)
Paramétrique : extension automatique du service fourni
à tout un ensemble de types (généricité).
Paramétrique
Ad-hoc
Polymorphisme
Surcharge
Coercition
Ad-hoc : expliciter toutes les formes possibles des
arguments
● nécessite une nouvelle définition pour chaque
nouveau type
7. Surcharge (overloading)
Surcharge des fonctions / méthodes / opérateurs :
i n t i = 3 + 5;
double d = 3.7 + 5.9;
string s = "3" + "5";
void f(int);
void f(double) ;
f(1);
f(1.0);
class A {
};
bool operator==(const A &, const A &);
A a1;
A a2;
if (a1 == a2) {
}
8. Coercition (conversion implicite)
La valeur d'un type est transformée en valeur d'un autre
type (cast / promotion) :
double v = 1 + 2.0;
memcpy(void *, const void*, size_t);
class A {
public :
operator int() const;
};
A a;
int i = a;
9. Polymorphisme paramétrique (1)
Se dit quand le code ne mentionne aucun type spécifique
et peut donc être utilisé de façon transparente avec
n'importe quel type.
// version surchargée
int min(int32, int32);
int min(uint32, uint32);
int min(int64, int64);
int min(uint64, uint64);
int min(float, float);
int min(double, double);
// version générique
template<typename T>
T min(T t1, T t2) {
return t1 <= t2 ? T1 : t2;
}
10. Polymorphisme paramétrique (2)
Principe : capturer les aspects statiques communs à
plusieurs algorithmes ou types de données.
En pratique : on utilise un type comme paramètre d'une
fonction générique :
vector<string> v;
v.insert(v.begin(), "hello");
v.insert(v.begin(), 5, "hello");
La STL (C++) combine la
surcharge avec le polymorphisme
paramétrique.
11. Deuxième classification (1985)
1985 : Cardelli et Wegner incluent les constructions
orientées objet :
Universel
Ad-hoc
Polymorphisme
Inclusion (POO)
Paramétrique (généricité)
Surcharge
Coercition Nouveau !
Ajout du polymorphisme d'inclusion (personnalisation du
comportement à l'exécution).
12. Polymorphisme d'inclusion (tadaa!!)
S'appuie sur l'héritage publique (spécialisation)
● les types appartiennent à une même hiérarchie de
classes
● relation de type « Est-Un » (« Is A ») entre les
(petits-)enfants et leur(s) parent(s)
Complexité plus importante à l'exécution
● la vtable coûte en temps exécution mais aussi
(surtout?) en espace mémoire...
13. Devinette !
Quelle est la différence entre surcharge et redéfinition ?
● Surcharge : polymorphisme au moment de la
compilation
● Redéfinition : polymorphisme au moment de
l'exécution
En fait, la redéfinition est une
surcharge dynamique !?!