Comment expliquer les concepts de programmation orientée objet à un enfant de 6 ans

Avez-vous remarqué comment les mêmes questions clichées sont toujours posées lors des entretiens d'embauche - encore et encore?

Je suis sûr que vous savez ce que je veux dire.

Par exemple:

Ou vous voyez-vous dans cinq ans?

ou, pire encore:

Quelle est selon vous votre plus grande faiblesse?

Ugh… donne-moi une pause. Je considère que répondre à cette question est une grande faiblesse! Quoi qu'il en soit, pas mon point.

Aussi triviales que puissent être ces questions, elles sont importantes car elles donnent des indices sur vous. Votre état d'esprit actuel, votre attitude, votre point de vue.

Lorsque vous répondez, vous devez être prudent, car vous pourriez révéler quelque chose que vous regretterez plus tard.

Aujourd'hui, je veux parler d'un type de question similaire dans le monde de la programmation:

Quels sont les grands principes de la programmation orientée objet?

J'ai été des deux côtés de cette question. C'est l'un de ces sujets qui est demandé si souvent que vous ne pouvez pas vous permettre de ne pas savoir.

Les développeurs juniors et débutants doivent généralement y répondre. Parce que c'est un moyen facile pour l'intervieweur de dire trois choses:

  1. Le candidat s'est-il préparé pour cet entretien?

    Des points bonus si vous entendez une réponse immédiatement - cela montre une approche sérieuse.

  2. Le candidat a-t-il dépassé la phase du tutoriel?

    Comprendre les principes de la programmation orientée objet (POO) montre que vous êtes allé au-delà du copier-coller à partir de didacticiels - vous voyez déjà les choses d'un point de vue plus élevé.

  3. La compréhension du candidat est-elle profonde ou superficielle?

    Le niveau de compétence sur cette question est souvent égal au niveau de compétence sur la plupart des autres sujets . Croyez-moi.

Les quatre principes de la programmation orientée objet sont l' encapsulation , l' abstraction , l' héritage ,et le polymorphisme .

Ces mots peuvent sembler effrayants pour un développeur junior. Et les explications complexes et excessivement longues de Wikipédia doublent parfois la confusion.

C'est pourquoi je veux donner une explication simple, courte et claire pour chacun de ces concepts. Cela peut sembler quelque chose que vous expliquez à un enfant, mais j'aimerais vraiment entendre ces réponses lorsque je mène une entrevue.

Encapsulation

Disons que nous avons un programme. Il a quelques objets logiquement différents qui communiquent entre eux - selon les règles définies dans le programme.

L'encapsulation est réalisée lorsque chaque objet garde son état privé , à l'intérieur d'une classe. Les autres objets n'ont pas d'accès direct à cet état. Au lieu de cela, ils ne peuvent appeler qu'une liste de fonctions publiques - appelées méthodes.

Ainsi, l'objet gère son propre état via des méthodes - et aucune autre classe ne peut le toucher à moins d'être explicitement autorisé. Si vous souhaitez communiquer avec l'objet, vous devez utiliser les méthodes fournies. Mais (par défaut), vous ne pouvez pas changer l'état.

Disons que nous construisons un petit jeu Sims. Il y a des gens et il y a un chat. Ils communiquent entre eux. Nous voulons appliquer l'encapsulation, donc nous encapsulons toute la logique «chat» dans unCatclasse. Cela peut ressembler à ceci:

Ici, «l'état» du chat est constitué des variables privéesmood , hungryet energy. Il a également une méthode privée meow(). Il peut l'appeler quand il veut, les autres classes ne peuvent pas dire au chat quand miauler.

Ce qu'ils peuvent faire est défini dans les méthodes publiquessleep() , play()et feed(). Chacun d'eux modifie en quelque sorte l'état interne et peut invoquer meow(). Ainsi, la liaison entre l'État privé et les méthodes publiques est établie.

C'est l'encapsulation.

Abstraction

L'abstraction peut être considérée comme une extension naturelle de l'encapsulation.

Dans la conception orientée objet, les programmes sont souvent extrêmement volumineux. Et des objets séparés communiquent beaucoup entre eux. Il est donc difficile de maintenir une grande base de code comme celle-ci pendant des années - avec des changements en cours de route.

L'abstraction est un concept visant à atténuer ce problème.

L' application des moyens d'abstraction que chaque objet doit seulement exposer un mécanisme de haut niveau pour l' utiliser.

Ce mécanisme doit masquer les détails de mise en œuvre interne. Il ne doit révéler que les opérations pertinentes pour les autres objets.

Pensez - une machine à café. Il fait beaucoup de choses et fait des bruits bizarres sous le capot. Mais tout ce que vous avez à faire est de mettre du café et d'appuyer sur un bouton.

De préférence, ce mécanisme devrait être facile à utiliser et devrait rarement changer avec le temps. Pensez-y comme un petit ensemble de méthodes publiques que toute autre classe peut appeler sans «savoir» comment elles fonctionnent.

Un autre exemple réel d'abstraction?

Pensez à la façon dont vous utilisez votre téléphone:

Vous interagissez avec votre téléphone en utilisant seulement quelques boutons. Que se passe-t-il sous le capot? Vous n'avez pas besoin de savoir - les détails de mise en œuvre sont masqués. Il vous suffit de connaître un court ensemble d'actions.

Les changements d'implémentation - par exemple, une mise à jour logicielle - affectent rarement l'abstraction que vous utilisez.

Héritage

OK, nous avons vu comment l'encapsulation et l'abstraction peuvent nous aider à développer et maintenir une grande base de code.

Mais savez-vous quel est un autre problème courant dans la conception POO?

Les objets sont souvent très similaires. Ils partagent une logique commune. Mais ils ne sont pas tout à fait les mêmes. Pouah…

Alors, comment réutiliser la logique commune et extraire la logique unique dans une classe distincte? Un moyen d'y parvenir est l'héritage.

Cela signifie que vous créez une classe (enfant) en dérivant d'une autre classe (parent). De cette façon, nous formons une hiérarchie.

La classe enfant réutilise tous les champs et méthodes de la classe parent (partie commune) et peut implémenter la sienne (partie unique).

Par exemple:

Si notre programme a besoin de gérer des enseignants publics et privés, mais aussi d'autres types de personnes comme les étudiants, nous pouvons implémenter cette hiérarchie de classes.

De cette façon, chaque classe ajoute uniquement ce qui lui est nécessaire tout en réutilisant la logique commune avec les classes parentes.

Polymorphisme

Nous en sommes au mot le plus complexe! Le polymorphisme signifie «plusieurs formes» en grec.

Nous connaissons donc déjà le pouvoir de l'héritage et l'utilisons avec bonheur. Mais il y a ce problème.

Disons que nous avons une classe parente et quelques classes enfants qui en héritent. Parfois, nous voulons utiliser une collection - par exemple une liste - qui contient un mélange de toutes ces classes. Ou nous avons une méthode implémentée pour la classe parente - mais nous aimerions aussi l'utiliser pour les enfants.

Cela peut être résolu en utilisant le polymorphisme.

En termes simples, le polymorphisme permet d'utiliser une classe exactement comme son parent, donc il n'y a pas de confusion avec le mélange de types.Mais chaque classe enfant garde ses propres méthodes telles quelles.

Cela se produit généralement en définissant une interface (parent) à réutiliser. Il décrit un tas de méthodes courantes. Ensuite, chaque classe enfant implémente sa propre version de ces méthodes.

À chaque fois qu'une collection (telle qu'une liste) ou une méthode attend une instance du parent (où les méthodes communes sont décrites), le langage se charge d'évaluer la bonne implémentation de la méthode commune - quel que soit l'enfant passé.

Jetez un œil à un croquis de la mise en œuvre des figures géométriques. Ils réutilisent une interface commune pour le calcul de la surface et du périmètre:

Le fait que ces trois figures héritant le parent Figure Interfacevous permet de créer une liste de mélange triangles, circleset rectangles. Et traitez-les comme le même type d'objet.

Ensuite, si cette liste tente de calculer la surface d'un élément, la méthode correcte est trouvée et exécutée. Si l'élément est un triangle, le triangleCalculateSurface()est appelé. Si c'est un cercle - alors cirlce'sCalculateSurface()est appelé. Etc.

Si vous avez une fonction qui opère avec une figure en utilisant son paramètre, vous n'avez pas à la définir trois fois - une fois pour un triangle, un cercle et un rectangle.

Vous pouvez le définir une fois et accepter un Figurecomme argument. Que vous passiez un triangle, un cercle ou un rectangle - tant qu'ils sont implémentés CalculateParamter(), leur type n'a pas d'importance.

J'espère que cela a aidé. Vous pouvez utiliser directement ces mêmes explications lors des entretiens d'embauche.

Si vous trouvez quelque chose encore difficile à comprendre, n'hésitez pas à demander dans les commentaires ci-dessous.

Et après?

Être prêt à répondre à l'un des classiques de toutes les questions d'entrevue est génial - mais parfois, vous n'êtes jamais appelé pour une entrevue.

Ensuite, je me concentrerai sur ce que les employeurs veulent voir chez un développeur junior et comment se démarquer lors de la recherche d'emploi.

Restez à l'écoute.