Dans ce chapitre, nous allons pouvoir mettre en application une autre notion essentielle de ce paradigme de programmation : l’héritage.
Un paradigme de programmation ? Qu’est-ce que c’est ?
Bonne question !
Par exemple, la programmation orientée objet et la programmation fonctionnelle sont aussi des paradigmes. Ces deux types de programmation ont un langage associé et des méthodes de programmation spécifiques.
Utilisez l’héritage pour ajouter des fonctionnalités
Pour mettre en application l’héritage, la meilleure méthode est de partir d’un exemple. Partons de notre projet fil rouge. Nous allons créer deux classes : une classe Movie
et une classe TvShow
.
class Movie {
constructor(title, releasedDate, duration) {
this._title = title
this._releasedDate = releasedDate
this._duration = duration
}
}
class TvShow {
constructor(title, numberOfEpisodePerSeason, numberOfSeasons) {
this._title = title
this._numberOfEpisodePerSeason = numberOfEpisodePerSeason
this._numberOfSeasons = numberOfSeasons
}
}
// Ici j'instancie quelques classes de films
const PredatorMovie = new Movie("Predator", 1987, 107)
const TerminatorMovie = new Movie("Terminator", 1984, 107)
const AlienMovie = new Movie("Alien", 1979, 117)
// Ici j'instancie quelques séries
const FriendsTvShow = new TvShow("Friends", 23, 10)
const ScrubsTvShow = new TvShow("Scrubs", 20, 9)
const CougarTownTvShow = new TvShow("Cougar Town", 13, 5)
Comme vous pouvez le constater, ces deux objets sont assez différents. Leurs propriétés ne sont pas du tout les mêmes.
Admettons que vous souhaitiez maintenant ajouter une fonctionnalité pour lancer le film ou la série via une URL, et idéalement sans trop refactoriser le code. C’est le moment d’utiliser l’héritage. ;)
Je vais donc créer dans un premier temps une classe Media
. Cette dernière contiendra la fonctionnalité pour lancer le film ou la série ; dans notre cas, la méthode s’appelle sobrement play :
class Media {
constructor(url) {
this._url = url
}
play() {
/**
* Ici, je ne lance pas le film, je fais simplement
* un console.log mais le résultat est le même ;)
*/
console.log(this._url)
}
}
Puis j’adapte mon code existant pour que les classes Movie
et TvShow
puissent se servir de cette fonctionnalité :
class Movie extends Media {
constructor(url, title, releasedDate, duration) {
super(url)
this._title = title
this._releasedDate = releasedDate
this._duration = duration
}
}
class TvShow extends Media {
constructor(url, title, numberOfEpisodePerSeason, numberOfSeasons) {
super(url)
this._title = title
this._numberOfEpisodePerSeason = numberOfEpisodePerSeason
this._numberOfSeasons = numberOfSeasons
}
}
Ici, vous noterez :
L’utilisation du mot clé
extends
. Ce dernier permet aux classesMovie
etTvShow
de pouvoir “récupérer” la fonctionnalité play ;L’utilisation du
super()
qui permet de passer des paramètres, ici en l'occurrence l’URL, à la classeMedia
.
Est-ce qu’on ne pourrait pas ajouter aussi la propriété title
à notre classe Media
? Elle comprend aussi l’attribut title
, non ?
Oui, on pourrait tout à fait faire ça.
En fait, pour cet exemple, j’ai choisi de me concentrer sur l’attribut URL, mais la classe Media
pourrait aussi récupérer title
.
Il ne nous reste plus qu’à tester notre feature :
// Je crée mon instance pour le film Predator et je renseigne bien l'URL
const PredatorMovie = new Movie("https//www.google.com", "Predator", 1987, 107)
// Je lance Predator via la méthode play de la classe Media
PredatorMovie.play()
Le JavaScript, un langage de prototypage
Vous arrivez au terme de ce chapitre mais avant de le conclure, nous allons revenir sur une notion abordée un peu plus haut : le prototypage !
Si vous vous souvenez bien, le JavaScript est un langage orienté objet. Or, ces objets sont créés par le biais de prototypes.
Mais attends, on vient de voir comment créer des objets via des classes, pas via des prototypes ? Je croyais que les prototypes, c’était l’ancienne méthode...
C’est vrai et je vous ai menti…😱
Quand vous utilisez le mot clé class
pour créer un objet en JavaScript, vous créez ce qu’on appelle un prototype. Tous les objets en JavaScript, aussi bien les objets natifs que les objets que vous allez créer, sont et seront des prototypes.
Mais alors, pourquoi est-ce que nous utilisons le mot clé class
et non le prototypage pour créer et manipuler nos objets ?
En fait, le mot class
nous permet de créer plus facilement et surtout de manière plus lisible des objets.
Et du coup, pourquoi nous expliquer cette notion de prototype ?
Tout simplement parce que :
Il est important que vous connaissiez cette notion pour déboguer votre code. Quand vous voyez
prototype
lors d’un débogage, vous devez automatiquement penser orienté objet.De nombreuses librairies n’utilisent pas encore le mot clé
class
. Il est donc très fortement probable que vous rencontriez des bases de code qui utilisent les prototypes et non les classes.
Ne surchargez pas vos types de natifs
Dernière chose avant de conclure. Il est possible de surcharger des types natifs en JavaScript pour leur ajouter des fonctionnalités ou comportements supplémentaires. Cela peut se faire très simplement, comme vous pouvez le voir dans le snippet de code ci-dessous :
/**
* Je surcharge ici le type natif String en
* lui ajoutant la méthode sayHello
*/
String.prototype.sayHello = function() {
console.log("Hello")
}
const firstName = "Thomas"
// J'appelle ma méthode sayHello ici
firstName.sayHello()
Cela dit, ce n’est pas parce que vous pouvez le faire, que vous devez le faire !
En résumé
L’héritage vous permet de “transférer” des propriétés et méthodes d’une classe à une autre. C’est l’un des mécanismes de l’orienté objet les plus essentiels.
Le JavaScript est un langage orienté objet de type prototype. Bien qu’il reste possible de créer des objets via les prototypes, vous allez utiliser le mot clé
class
pour créer des objets dans ce cours.
Vous êtes maintenant incollable sur la programmation orientée objet, l’héritage et le prototypage ; passez au chapitre suivant pour découvrir les design patterns. :)