Un jour, je suis allé sur un chat Stack Overflow et j'ai vu une phrase qui disait que l'hérédité, l'incapsulation et le polymorphisme sont les piliers de la POO (dans le sens où ils sont fondamentaux, une semelle de construction).
En outre, il y a une question similaire, qui m'a été posée très souvent lors d'examens universitaires et d'entretiens d'embauche, et la bonne réponse a toujours été la déclaration prononcée dans le titre de la question ("Oui, l'héritage, l'encapsulation et le polymorphisme sont les piliers de la POO ).
Mais dans le chat Stack Overflow, j'ai été sévèrement ridiculisé, les participants étaient fortement en désaccord avec une telle déclaration. Alors, quel est le problème avec cette déclaration?
Les programmeurs semblent-ils être formés à différentes choses dans les collèges post-soviétiques et américains?
L'héritage, l'encapsulation et le polymorphisme ne sont-ils pas considérés comme les piliers de la POO par les programmeurs américains / britanniques?
la source
Réponses:
Ils sont considérés comme des piliers par de nombreux programmeurs, et de nombreux collèges enseignent OO de cette façon.
Malheureusement, c'est aussi une vue à courte vue.
La POO a très peu de fondement, car en réalité, elle est très conceptuelle: "Abordez la conception de votre programme en pensant aux choses comme des objets - des ensembles cohérents de données et de fonctionnalités."
Et tandis que la conception de programme moderne a une mauvaise vue de faire les choses de «façon purement OO», la plupart des programmeurs qualifiés conviendront que les principes SOLIDES (ou certains sous-ensembles) sont de meilleurs candidats pour les «piliers de la programmation orientée objet» (même s'ils s'applique bien aux non-POO). Ceux-ci ne fonctionnent pas du tout avec ces termes. Au lieu de cela, ils utilisent les concepts d'entités logicielles (dont les objets sont un), d'interfaces (dont un C # / Java / etc. en
interface
est un), d'abstraction et de sous-typage (dont l'héritage est une forme).la source
tl; dr: Vous pouvez avoir un héritage sans OO, vous pouvez avoir une encapsulation sans OO, vous pouvez avoir un polymorphisme sans OO, vous pouvez même avoir les trois à la fois sans OO. D'un autre côté, vous pouvez avoir OO sans héritage. De plus, il existe différents types d'encapsulation (orientés ADT et OO), IOW n'est pas toute l'encapsulation est OO.
Version longue:
Le terme "programmation orientée objet" a été inventé par Alan Kay, donc il doit décider ce que cela signifie. Et il le définit ainsi :
En ce qui concerne l'implémentation, la messagerie est un appel de procédure à liaison tardive, et si les appels de procédure sont à liaison tardive, vous ne pouvez pas savoir au moment de la conception ce que vous allez appeler, vous ne pouvez donc pas faire d'hypothèses sur la représentation concrète de l'état. Donc, il s'agit vraiment de messagerie, la liaison tardive est une implémentation de la messagerie et l'encapsulation en est la conséquence.
Il a ensuite précisé que " la grande idée est la" messagerie " ", et regrette de l'avoir appelé "orienté objet" au lieu de "orienté message", car le terme "orienté objet" met l'accent sur la chose sans importance (objets ) et détourne l'attention de ce qui est vraiment important (messagerie):
(Bien sûr, aujourd'hui, la plupart des gens ne se concentrent même pas sur les objets mais sur les classes, ce qui est encore plus faux.)
La messagerie est fondamentale pour l'OO, à la fois comme métaphore et comme mécanisme.
Si vous envoyez un message à quelqu'un, vous ne savez pas ce qu'il en fait. La seule chose que vous pouvez observer, c'est leur réponse. Vous ne savez pas s'ils ont traité le message eux-mêmes (c'est-à-dire si l'objet a une méthode), s'ils ont transmis le message à quelqu'un d'autre (délégation / mandataire), s'ils l'ont même compris. C'est à cela que sert l'encapsulation, c'est à cela que sert OO. Vous ne pouvez même pas distinguer un proxy de la vraie chose, tant qu'il répond comme vous l'attendez.
Un terme plus "moderne" pour "messagerie" est "envoi de méthode dynamique" ou "appel de méthode virtuelle", mais qui perd la métaphore et se concentre sur le mécanisme.
Des points similaires sont également soulignés dans On Understanding Data Abstraction, Revisited by William R. Cook et également sa Proposition de définitions modernes et simplifiées de "Object" et "Object Oriented" .
Dans Smalltalk-72, il n'y avait même pas d'objets! Il n'y avait que des flux de messages qui ont été analysés, réécrits et redirigés. Les premières méthodes sont arrivées (méthodes standard pour analyser et rediriger les flux de messages), puis les objets (regroupements de méthodes qui partagent un certain état privé). L'héritage est venu beaucoup plus tard et les classes n'ont été introduites que comme moyen de prendre en charge l'héritage. Si le groupe de recherche de Kay connaissait déjà les prototypes, ils n'auraient probablement jamais introduit de cours en premier lieu.
Chaque programmeur devrait lire On Understanding Abstraction Data, Revisited . Il explique en détail quelle est exactement la différence entre les objets et les types de données abstraits. Il donne des exemples en utilisant Java, et qui est extrêmement pertinente à cette question, parce que dans les deux exemples d'ADT et les exemples d'objets qu'il utilise l' héritage, l' encapsulation et le polymorphisme, mais seulement l' un des exemples est orienté objet! En d'autres termes: vous pouvez avoir l'héritage, l'encapsulation et le polymorphisme, vous pouvez même avoir les trois à la fois et toujours pas d'OO.
D'un autre côté, vous pouvez avoir OO sans héritage. Comme je l'ai laissé entendre ci-dessus: les versions originales de Smalltalk (le langage conçu par Alan Kay, l'inventeur du terme "programmation orientée objet") n'avaient pas d'héritage.
Dernier point, mais certainement pas le moindre, le Traité d'Orlando traite de la délégation comme alternative à l'héritage et comment les différentes formes de délégation et d'héritage conduisent à différents points de conception dans l'espace de conception des langages orientés objet. (Notez qu'en fait, même dans les langages qui prennent en charge l'héritage, comme Java, les gens apprennent à l'éviter, ce qui indique à nouveau qu'il n'est pas nécessaire pour OO.)
la source