Un comble, non ?

Imaginez juste un instant la puissance d'un code tel que :

$facture = new facture();
foreach ($lignesFacture as $ligneFacture)
{
$facture += $ligneFacture;
}
echo $facture->total;

Vous voyez ou je veux en venir ?

Actuellement, pour faire une telle chose proprement, il faut faire

$facture = new facture();
foreach ($lignesFacture as $ligneFacture)
{
$facture->addLigne($ligneFacture);
}
echo $facture->total;

De mon point de vue, au niveau lisibilité du code, il n'y a pas photo.

Sans compter qu'il devient possible d'introduire de la généricité dans les algorithmes avec ce système, pour par exemple additioner n'importe quoi sans se soucier de la nature de ce qu'on additionne ;

$facture = new facture();
$elements = array(new ligneFacture(), new tva(), new client());
foreach ($elements as $element)
{
$facture += $element;
}

Autre paradoxe, s'il est possible de surcharger une méthode parente dans une classe fille, Il n'est pas possible de définir une méthode avec un même nom mais acceptant des arguments différents au sein d'une même classe.

C'est interdit. C'est pas bien. Ca tue les bébés phoques sur la banquise. Et puis d'abord, ca servirait à quoi, hein ?

Bonne question...

Actuellement, si une méthode doit effectuer un traitement différent en fonction des argument qu'elle reçoit, il y a deux stratégies possibles.

La première consiste à utiliser un code du type :

swtich (gettype($argument))
case 'int': ...
case 'array': ...
case 'stdClass': ...

Ainsi, la méthode sait ce qu'elle doit faire en fonction du type de son argument.

Si cette stratégie est jouable pour des fonctions qui ne prennent qu'un argument, elle se transforme vite en chemin de croix à partir du moment ou le nombre d'arguments et de types possibles vont croissant.

La seconde stratégie consiste à définir plusieurs méthodes qui assurent la même fonction mais qui portent des noms différents, comme par exemple :

function insertFromArray(array $array) {...}

function insertFromObject(stdClass $object) {...}

Cette façon de faire à l'inconvénient d'obliger le programmeur à trouver des noms de méthodes cohérents et qui ressemble à quelque chose. Corollaire : le code devient truffé de méthodes portant un nom à rallonge qui font fondamentalement la même chose, et le développeur se prend la tête pour autre chose que le code métier.

Encore une fois, rien de bien grave, hormis que :

  • le code perd en lisibilité et devient donc moins facile à relire, maintenir, et corriger.
  • le développeur perd la puissance de la généricité, puisque plus rien n'est générique.
  • si un nouveau type doit être géré, le développeur doit se creuser le crâne pour trouver un nom de méthode qui ressemble à quelque chose et qui ne fasse pas 137 caractères de long.

En clair, nous sommes loin de la panacé, dans un cas comme dans l'autre.

La surcharge de méthode permettrait d'apporter une solution beaucoup plus élégante à cette problèmatique en permettant la définition de plusieurs méthodes de même nom mais disposant de signature différente.

Si PHP supportait vraiment la surcharge, les deux exemples de code précédent pourraient donc être remplacé avantageusement par le code suivant :

function insert(array $array) {...}

function insert(stdClass $objet) {...}

Avec cette solution, le code reste lisible, facile à comprendre, et il devient possible d'exploiter la puissance de la généricité sans aucun problème.

Et pour peu que le développeur mixe cela avec la surcharge d'opérateur exposée précédement, le paradis n'est plus très loin.

Mais pour l'instant, il est inacessible, à moins de se résoudre à modifier PHP lui même ou passer par une extension très peu répandue.

Cependant, comme je l'ai déjà dit, PHP est parfois capable d'évoluer dans le bon sens, et peut être qu'un jour il deviendra un langage qui supporte complétement le modèle objet.

Alors, j'ai encore un peu d'espoir...