Je pense qu'il y a quelques facteurs qui n'ont pas encore été mentionnés.
Tout d’abord, du moins dans la "pure OOP" (par exemple, Smalltalk) où tout est un objet, vous devez tordre votre esprit dans une configuration peu naturelle pour penser à un nombre (pour un seul exemple) comme un objet intelligent au lieu de juste une valeur - car en réalité, 21
(par exemple) n'est vraiment qu'une valeur. Cela devient particulièrement problématique lorsque d’un côté on vous dit que l’un des grands avantages de la POO est de modéliser plus fidèlement la réalité, mais vous commencez par prendre ce qui ressemble beaucoup à une vue inspirée par le LSD des parties les plus fondamentales et les plus évidentes de réalité.
Deuxièmement, l'héritage en POO ne suit pas de près les modèles mentaux de la plupart des gens. Pour la plupart des gens, classer les choses de manière plus spécifique n’a pas la moindre ressemblance avec les règles absolues nécessaires pour créer une hiérarchie de classes qui fonctionne. En particulier, créer un class D
qui hérite d’un autre class B
signifie que les objets de class D
partage partagent absolument, positivement toutes les caractéristiques de class B
. class D
peut ajouter des caractéristiques nouvelles et différentes, mais toutes les caractéristiques de class B
doivent rester intactes.
En revanche, lorsque les gens classifient les choses mentalement, ils suivent généralement un modèle beaucoup plus souple. Par exemple, si une personne établit des règles sur ce qui constitue une classe d'objets, il est assez typique que presque toutes les règles puissent être enfreintes tant que suffisamment d'autres règles sont suivies. Même les quelques règles qui ne peuvent pas vraiment être enfreintes peuvent presque toujours être "étirées" un peu.
Juste par exemple, considérons "voiture" en tant que classe. Il est assez facile de voir que la grande majorité de ce que la plupart des gens considèrent comme des "voitures" a quatre roues. La plupart des gens, cependant, ont vu (au moins une photo de) une voiture avec seulement trois roues. Quelques-uns d'entre nous du bon âge se souviennent également d'une voiture de course ou de deux voitures du début des années 80 (ou plus) à six roues - et ainsi de suite. Cela nous laisse fondamentalement trois choix:
- N'affirmez rien sur le nombre de roues d'une voiture - mais cela tend à laisser supposer implicitement que ce sera toujours 4 et que le code risque de casser pour un autre numéro.
- Affirmer que toutes les voitures ont quatre roues et classer simplement les autres comme "pas des voitures" même si nous savons qu’elles le sont vraiment.
- Concevez cette classe de manière à permettre la variation du nombre de roues, juste au cas où, même s'il y a de fortes chances pour que cette capacité ne soit jamais nécessaire, utilisée ou testée correctement.
L’enseignement de la programmation orientée objet vise souvent à créer d’énormes taxonomies - par exemple, des morceaux de ce qui serait une hiérarchie géante de toute la vie connue sur la Terre, ou quelque chose du même ordre. Cela soulève deux problèmes: tout d’abord, cela a tendance à amener beaucoup de gens à se concentrer sur d’énormes quantités d’informations qui n’ont absolument rien à voir avec la question à l’examen. À un moment donné, j'ai assisté à une discussion assez longue sur la manière de modéliser les races de chiens et sur la question de savoir si, par exemple, le "caniche miniature" devait hériter du "caniche de taille normale", ou inversement, ou s'il devait exister une base abstraite "Caniche" "class, avec" caniche grandeur nature "et" caniche miniature "qui en héritent tous les deux. Ce qu’ils semblaient tous ignorer, c’était que l’application était censée permettre de garder trace des permis de chiens,
Deuxièmement et surtout, cela amène à mettre l’accent sur les caractéristiques des articles plutôt que sur les caractéristiques importantes pour la tâche à accomplir. Elle conduit vers les choses de modélisation comme ils sont, où ( la plupart du temps) ce qui est vraiment nécessaire est la construction du modèle le plus simple qui comblera nos besoins, et d' utiliser l' abstraction pour répondre aux nécessaires sous-classes pour adapter l'abstraction que nous avons construit.
Enfin, je le répète: nous suivons lentement le même chemin emprunté par les bases de données au fil des ans. Les premières bases de données suivaient le modèle hiérarchique. Hormis le fait de se concentrer exclusivement sur les données, il s’agit d’un héritage unique. Pendant un court laps de temps, quelques bases de données ont suivi le modèle de réseau - essentiellement identique à l'héritage multiple (et vu sous cet angle, les interfaces multiples ne sont pas assez différentes des classes de base multiples pour être remarquées ou gérées de manière pertinente).
Cependant, il y a bien longtemps, les bases de données ont largement convergé vers le modèle relationnel (et même si elles ne sont pas du code SQL, les bases de données "NoSQL" actuelles sont aussi relationnelles à ce niveau d'abstraction). Les avantages du modèle relationnel sont suffisamment connus pour que je ne me permette pas de les répéter ici. Je rappellerai simplement que l’analogue le plus proche du modèle relationnel que nous avons en programmation est la programmation générique (et désolé, mais malgré son nom, les génériques Java, par exemple, ne sont pas vraiment éligibles, bien qu’ils constituent un tout petit pas dans la bonne direction).