Dans les années 60, il existait déjà l'impératif brutasse de l'assembleur. Il existait clairement le fonctionnel. Et il faudrait vérifier pour le déclaratif du Prolog – certes non mainstream. Toujours est-il que le procédural est loin d'être le seul paradigme majeur.
Le principe de fonctionnement de la POO est basé, comme dit plus haut, sur le fait que tout élément est objet et que chaque objet a un objet parent et éventuellement un objet enfant.
Non, il n'y a pas forcément de parent, de même qu'il n'y a pas forcément d'enfant. C'est un détail.
L'objet, c'est d'abord un moyen de mettre en œuvre des services au travers d'abstractions, (via l'encapsulation), puis c'est une façon (dynamique?) de mettre en œuvre des points de variations (-> le polymorphisme d'inclusion, qui va s'appuyer sur l'héritage en effet)
La classe Personne
que tu présentes est un très mauvais exemple de POO. Ce n'est qu'une agrégation de données, dans une syntaxe imposée par un langage à œillères OO. La différence que tu présentes avec du procédural ne se situe qu'au niveau du sucrage syntaxique de l'initialisation de l'agrégation. Elle ne touche pas les fondements de la POO. A la limite, on pourrait évoquer qu'un constructeur positionne l'invariant de la Personne
, mais ce n'est pas l'objectif premier de l'OO. C'est un bonus important de beaucoup de langages OO, mais pas de tous je crains.
Si tu veux un exemple de différence entre la POO et le reste, c'est ceci qu'il faut regarder : http://fr.openclassrooms.com/forum/sujet/comment-le-c#message-87210210
J'insiste sur les setters : c'est l'antithèse de la POO : la prog orientée données. Les getters, ne provoquent pas des ruptures d'encapsulation aussi importantes quand les langages permettent un accès en read-only, mais ce n'est pas toujours le cas.
La vision de l'héritage est également trop technique à goût : orientée vers les fonctions mises à dispositions, et non vers la substituabilité qui est l'objectif majeur de l'héritage.
Concernant extends/implements, c'est de la bidouille technique Java qui passe à côté de la dualité de l'héritage qui est vraiment importante: substituabilité (cf LSP) VS import de code (sans substituabilité).
Bref, je dirai de reprendre les présentations. Si tu veux rentrer dans la technique, alors le tuto de conception devient un tuto de langage. Mais il y a déjà bien assez de choses à dire sur la conception OO, et de mythes à briser.
EDIT2: Tiens, j'avais manqué ça
Il existe même sur certains langages en OO (orienté objet) comme PHP, un destructeur qui sera appelé lors de la destruction volontaire (ou involontaire) de l'objet. Mais on utilise rarement cette méthode…
Les destructeurs sont juste la propriété du C++ qui fait toute la différence avec le C. Ce n'est certes pas une caractéristique fondamentale des langages OO (vu que peu en ont), mais c'est le moyen (déterministe et implicite) par lequel on finalise tout, sans exceptions. -> fichiers, mémoire, sockets, pots de peinture, … En Java, tu as le dispose-pattern (try
+finally
) (déterministe et explicite) et le try-with-ressources (?) depuis la v7.
Bref, les destructeurs sont au centre de ce que l'on appelle le C++ Moderne. C'est grâce à eux que l'on a des codes maintenables sans fuites ni rien. Donc, peut-être en PHP c'est le cas, mais en C++, on n'utilise certainement pas rarement les destructeurs. Bien au contraire on en use en permanence.
fin EDIT2
PS: Désolé si mon message peut paraitre "rude", il faut dire qu'il est tellement facile de s'arracher une jambe en C++ que l'on devient super tatillons sur la théorie qui l'on peut appliquer. ^^'
Je sais que la tâche est rude. Bon courage.
EDIT: PPS: @Looping, ce que fait la notion d'interface, c'est qu'elle force aussi le respect du LSP. Et sans LSP il ne peut pas y avoir d'héritage multiple qui tienne la route.