Cela va même plus loin que cela. Il ne s'agit que de la partie syntaxico-visible de l'iceberg.
La question qu'il faut se poser est : "est-ce que les objets de la nouvelle classes seront des représentants de la classe ancêtre" <=> "peut-on substituer des objets fils là où l'on attend des objets du type parent?"
Bien souvent, on va se rendre compte que non -- dans le cas des conteneurs.
- s'il s'agit de rajouter des services, on peut les rajouter à côté. Ils feront toujours parti de l'interface publique, étendue de l'objet.
- Il est parfois acceptable (!= ultimement propre, ...) de dériver pour les rajouter tant qu'il n'y a pas de nouvelle donnée membre (pour éviter d'éventuels slicings), et que l'on ne joue pas à détruire polymorphiquement.
- s'il s'agit de modifier des services, ben ...on casse vite les contrats établis par le parent. L'exemple typique, c'est la définition d'une liste triée à partir d'un liste. Exemple typique où l'héritage (public en C++, quelconque en Java) n'est pas acceptable. Ici, on ne veut pas "être utilisé en place de" , on veut "réutiliser" => héritage privé ou délégation queconque
- s'il s'agit de spécialiser le conteneur pour des objets précis pour lesquels on veut un traitement suplémentaire bien précis, de nouveau, on bride le contrat initial. On veut réutiliser du code, pas être utilisés en place de.
Ici le polymorphisme d'inclusion (impliqué par l'héritage public) est rarement la solution si on veut factoriser le code. Au contraire du polymorphisme paramétrique et statique des templates du C++.
[^] # Re: Appels surchargés
Posté par lmg HS (site web personnel) . En réponse au message Surcharge d'opérateur : appel de l'opérateur de la classe mère. Évalué à 1.
La question qu'il faut se poser est : "est-ce que les objets de la nouvelle classes seront des représentants de la classe ancêtre" <=> "peut-on substituer des objets fils là où l'on attend des objets du type parent?"
Bien souvent, on va se rendre compte que non -- dans le cas des conteneurs.
- s'il s'agit de rajouter des services, on peut les rajouter à côté. Ils feront toujours parti de l'interface publique, étendue de l'objet.
- Il est parfois acceptable (!= ultimement propre, ...) de dériver pour les rajouter tant qu'il n'y a pas de nouvelle donnée membre (pour éviter d'éventuels slicings), et que l'on ne joue pas à détruire polymorphiquement.
- s'il s'agit de modifier des services, ben ...on casse vite les contrats établis par le parent. L'exemple typique, c'est la définition d'une liste triée à partir d'un liste. Exemple typique où l'héritage (public en C++, quelconque en Java) n'est pas acceptable. Ici, on ne veut pas "être utilisé en place de" , on veut "réutiliser" => héritage privé ou délégation queconque
- s'il s'agit de spécialiser le conteneur pour des objets précis pour lesquels on veut un traitement suplémentaire bien précis, de nouveau, on bride le contrat initial. On veut réutiliser du code, pas être utilisés en place de.
Ici le polymorphisme d'inclusion (impliqué par l'héritage public) est rarement la solution si on veut factoriser le code. Au contraire du polymorphisme paramétrique et statique des templates du C++.