If you're seeing this message, it means we're having trouble loading external resources on our website.

Si vous avez un filtre web, veuillez vous assurer que les domaines *. kastatic.org et *. kasandbox.org sont autorisés.

Contenu principal

Résumé : la conception orientée objet

Voici un résumé de ce que nous avons couvert dans ce module sur la conception orienté objet.
Quand nous créons des programmes, nous constatons souvent que nous voulons utiliser des objets différents, partageant des propriétés similaires (comme, par exemple, des chats, avec des couleurs de fourrure et des tailles légèrement différentes, ou des boutons, avec des libellés et des positionnements différents). Nous souhaitons être capable de décrire à quoi ressemble un chat, en général et créer deux chats particuliers, qui seront similaires d'un certain côté et différents de l'autre. Pour faire cela, nous utilisons une conception orientée objet pour définir des types d'objet et créer de nouvelles instances de ces objets.
Pour définir un type d'objet en JavaScript, on doit tout d'abord définir une "fonction constructeur". C'est la fonction que nous utiliserons à chaque fois que nous voudrons créer une nouvelle instance de ce type d'objet. Voici une fonction constructeur pour un type d'objet Livre:
var Livre = function(titre, auteur, nbPages) {
     this.titre = titre;
     this.auteur = auteur;
     this.nbPages = nbPages;
     this.pageActuelle = 0;
};
La fonction prend en arguments les caractéristiques (donc différentes en fonction des livres) du livre : le titre, l'auteur et le nombre de pages. Puis, elle définit les propriétés initiales de l'objet, en fonction de ces arguments, en utilisant le mot clé this. Quand nous utilisons this dans un objet, nous nous référons à l'instance actuelle d'un objet. Nous avons besoin de stocker les propriétés par l'intermédiaire de this pour nous assurer que nous pourrons les récupérer plus tard.
Pour créer une instance de l'objet Livre, nous déclarons une nouvelle variable pour l'enregistrer, en utilisant le mot clé new, suivi du nom de la fonction constructeur, et des arguments attendus :
var livre = new Livre("Le Robot qui rêvait", "Isaac Asimov", 320);
Nous pouvons ensuite accéder aux propriétés enregistrées dans l'objet en utilisant la notation pointée :
println("J'ai adoré " + livre.titre); // J'ai adoré Le Robot qui rêvait
println(livre.auteur + " est mon auteur préféré"); // Isaac Asimov est mon auteur préféré
Montrons, en contraste, rapidement, ce qui aurait pu se passer si nous n'avions pas défini notre fonction constructeur correctement :
var Livre = function(titre, auteur, nbPages) {
};
var livre = new Livre("Petit frère", "Cory Doctorow", 380);
println("J'ai adoré " + livre.titre); // J'ai adoré undefined
println(livre.auteur + " est mon auteur préféré"); // undefined est mon auteur préféré
Si nous passons les arguments à la fonction constructeur mais ne les enregistrons pas explicitement par l'intermédiaire de this, alors nous ne pourrons pas y accéder par la suite ! L'objet les aura oubliés.
Quand nous définissons des types d'objet, nous voulons souvent y associer, et des propriétés, et des comportements (comme le fait que tous nos objets chats doivent pouvoir miauler() et manger()). Il nous faut donc pouvoir attacher des fonctions à nos définitions de types d'objet, et on peut le faire en les définissant sur ce qu'on appelle le prototype de l'objet :
Livre.prototype.lireJusquALaFin = function() {
     this.pageActuelle = this.nbPages;
     println("Vous avez lu " + this.nbPages + " pages !");
};
C'est comme si nous définissions une fonction normalement, sauf que nous l'attachons au prototype de Livre plutôt que de la définir globalement. De cette façon, JavaScript sait que c'est une fonction qui peut être appelée à partir d'un objet Livre et que cette fonction a accès aux propriétés (par l'intermédiaire de this) de cet objet.
On peut alors appeler la fonction (qu'on appelle une méthode, car elle est attachée à un objet), de la façon suivante :
var livre = new Livre("La Ferme des animaux", "George Orwell", 112);
livre.lireJusquALaFin(); // Vous avez lu 112 pages !
N'oubliez pas, tout l'intérêt de la conception orientée objet est qu'elle nous facilite la création d'objets apparentés (instances d'objet). Voyons cela dans ce code :
var pirate = new Livre("Pirate Cinema", "Cory Doctorow", 384);
var passeur = new Livre("Le Passeur", "Lois Lowry", 179);
var tuck = new Livre("La Source enchantée", "Natalie Babbit", 144);

pirate.lireJusquALaFin(); // Vous avez lu 384 pages !
passeur.lireJusquALaFin(); // Vous avez lu 179 pages !
tuck.lireJusquALaFin(); // Vous avez lu 144 pages !
Ce code crée trois livres semblables (ils ont les mêmes noms de propriétés et de comportement) et en même temps différents (les valeurs ne sont pas les mêmes). Joli, non ?
Maintenant, si vous regardez le monde, les chats et les chiens représentent deux types d'objet différents, donc vous créeriez probablement deux types d'objets différents si vous deviez programmer un Chat et un Chien. Un chat pourrait miauler() et un chien pourrait aboyer(). Mais ils sont aussi semblables (un chat et un chien peuvent manger(). Ils ont tous les deux un age, une dateNaissance et une dateDeces). Ce sont tous les deux des mammifères, et ça veut dire qu'ils partagent beaucoup de choses en commun, même si ils sont différents.
Dans ce cas, nous utiliserons la notion d'héritage. Un type d'objet peut hériter des propriétés et du comportement d'un type d'objet parent, tout en ayant ses propres propriétés et comportement. Les Chats et les Chiens peuvent hériter de Mammifere, de façon à ne pas avoir à inventer le comportement manger(). Comment s'y prendre pour faire cela en JavaScript ?
Retournons à notre exemple de livre, et disons que Livre est le type d'objet "parent" , et que nous voulons que les types d'objet suivants héritent de lui : LivrePoche et LivreNumerique.
Un livre de poche est comme un livre, mais il est différent sur une chose, au moins pour notre programme : il a une image de couverture. Donc, notre constructeur doit prendre quatre arguments, pour tenir compte de cette information supplémentaire :
var LivrePoche = function(titre, auteur, nbPages, couverture) {
     // ...
}
Maintenant, nous ne voulons pas refaire le travail que nous avons déjà réalisé dans le constructeur de Livre, c'est-à-dire enregistrer les trois premiers arguments (nous voulons conserver l'avantage du fait que le code doit être le même). On peut donc appeler le constructeur de Livre à partir du constructeur de LivrePoche, en lui passant les arguments :
var LivrePoche = function(titre, auteur, nbPages, couverture) {
     Livre.call(this, titre, auteur, nbPages);
     // ...
};
Il nous faut cependant enregistrer la propriété couverture dans l'objet. Nous avons donc besoin d'une ligne supplémentaire pour tenir compte de cela :
var LivrePoche = function(titre, auteur, nbPages, couverture) {
     Livre.call(this, titre, auteur, nbPages);
     this.couverture = couverture;
};
Maintenant, nous avons un constructeur pour notre LivrePoche, qui offre l'avantage de partager les mêmes propriétés que Livre, mais nous voulons aussi que notre LivrePoche hérite de ses méthodes. Voici comment nous procédons, en demandant au programme d'initialiser le prototype de LivrePoche avec le prototype de Livre :
LivrePoche.prototype = Object.create(Livre.prototype);
Nous pourrions aussi vouloir attacher des comportements propres au livre de poche, comme la possibilité de le brûler. Et nous pouvons le faire en définissant des fonctions sur le prototype, en écrivant, après la ligne ci-dessus :
LivrePoche.prototype.bruler = function() {
     println("Mon Dieu, vous avez brûlé " + this.nbPages + " pages !");
     this.nbPages = 0;
};
Et maintenant, on peut créer un nouveau livre de poche, le lire en entier, puis le brûler !
var calvin = new LivrePoche("Calvin & Hobbes, l'essentiel", "Bill Watterson", 256, "http://ecx.images-amazon.com/images/I/61M41hxr0zL.jpg");

calvin.lireJusquALaFin(); // Vous avez lu 256 pages !
calvin.bruler(); // Mon Dieu, vous avez brûlé 256 pages !
(Bon, nous n'allons pas le brûler pour de vrai, car c'est un très bon livre, mais si nous étions coincés dans un désert de glace, manquant désespérément de chaleur, proche de la mort...)
Et maintenant, vous voyez comment nous pouvons utiliser les principes de la conception orientée objet en JavaScript pour créer des structures de données plus complexes pour vos programmes et modéliser au mieux votre univers de programmation.

Vous souhaitez rejoindre la discussion ?

  • hopper cool style l'avatar de l’utilisateur Christophe Noblanc
    Hi,
    I would suggest some improvements in this article to make it easier to understand for readers. For exemple, when you explain a concept using Cats & Dog & Mammal, then continue by using this example in the coding. At the end, you could use an other example about books, and show how to implement it but mixing both can be harder to understand.
    (It's just an opinion & suggestion)
    Thanks a lot for this content as it's not easy to find clear explanations about the OOP concepts...

    Also, I would suggest to use both term "object type" and "class" as we can see the "class" in a lot of other CS languages (Java,...), documents and books that use OOP...
    (20 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • aqualine ultimate style l'avatar de l’utilisateur 491254
    Je n'ai rien compris au 3 defis precedent et n'en ai reussis aucun, n'y aurais-t-il pas une video explicative. Merci d'avance
    (4 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • winston default style l'avatar de l’utilisateur walidhireche95
    aide moi SPV
    qui a trouver la 4 ème Étape j' bien fait Ecrire le code mais tjr rein
    SmileyFace.prototype.speaK = function(mm){
    text(mm,this.centerX,this.centerY);
    };
    face.draw();
    face.speaK("donner la parole au Smiley");
    (4 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • duskpin sapling style l'avatar de l’utilisateur Meriem Samai
    Je n'arrive pas à finir le défi: le smiley, je ne sais pas quoi mettre à l'intérieur des crochets après SmileyFace.prototype.draw = function(), j'ai besoin d'aide svp !
    (3 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • hopper cool style l'avatar de l’utilisateur Ilyas
    Pour ceux qui ne comprennent rien et qui voudraient voir des videos expliquant plus de choses, changer la langue de khan academy en anglais. Il y aura une ou deux videos en plus dont une sur l'intro.
    (3 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • blobby green style l'avatar de l’utilisateur Noémie Decobert
    Je n'arrive pas à finir le défi "le producteur de fleurs", simplement parce que l'étape 7 se trouve sous l'image du code.
    (3 votes)
    Default Khan Academy avatar l'avatar de l’utilisateur
  • hopper cool style l'avatar de l’utilisateur laimeche160
    j'ai enormement de difficulte a comprendre la conception oriente objet ...
    (1 vote)
    Default Khan Academy avatar l'avatar de l’utilisateur
Vous comprenez l'anglais ? Cliquez ici pour participer à d'autres discussions sur Khan Academy en anglais.