• 8 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 28/05/2024

Héritez de nouvelles connaissances

Vous commencez maintenant à avoir une bonne idée de ce qu'est la POO. Et dans ce chapitre, nous allons découvrir ce qui fait toute sa puissance : l'héritage !

Découvrez l'héritage

Comme c'est un chapitre important, je ne vais pas arriver à vous l'expliquer tout seul. C'est la raison pour laquelle je vous présente Bob, mon assistant dans ce chapitre.

Bob, un chien en peluche
Bob

Essayons de représenter Bob en orienté objet. Bob a une taille, un poids et une couleur, il peut aboyer, courir, manger, dormir.

Le diagramme Dog contient toutes les propriétés et méthodes de Bob : size, weight, color, bark, eat, sleep et run.
Bob en orienté objet

Certes, on pourrait le décrire plus précisément, mais ce n'est déjà pas mal. Laissez-moi maintenant vous présenter Raoul.

Raoul, un dragon en peluche
Raoul

Raoul et Bob sont évidemment très différents. Essayons de décrire Raoul en orienté objet. Raoul a une taille, un poids et une couleur. Il peut cracher du feu, manger, dormir, voler.

On ajoute le diagramme de Raul : size, weight, color, spit fire, eat, sleep et fly.
Bob et Raul en orienté objet

Hmmm... Selon notre classification, il semblerait que les classes Dragon et Dog ne soient pas si différentes. La plupart de leurs propriétés et méthodes sont identiques. Donc si on devait écrire l'implémentation des méthodes, on ferait deux fois la même chose. Or un développeur déteste se répéter ! On va donc utiliser l'héritage !

L'héritage permet de créer un arbre de classe. Dans notre exemple, nous avons deux animaux qui partagent des caractéristiques communes. En fait, on aurait pu décrire une classe Animal comme ceci :

Animal contient size, weight, color, eat et sleep.
Animal en orienté objet

Oui, mais le problème, c'est qu'on a été obligé d'enlever certaines méthodes comme bark ou fly , car elles ne sont pas valables pour tous les animaux. Il faut que l'on puisse garder nos classes Dog et Dragon pour gérer ces spécificités.

Alors que fait-on ? Nous allons modifier Dog et Dragon pour supprimer tout ce qui est commun, et qui du coup peut être mis dans la classe Animal . Et on va dire que les classes Dragon et Dog héritent de la classe Animal. On peut dire que  Dragon  et  Dog  sont les classes "filles" de la classe "mère",  Animal  .

On supprime les propriétés et méthodes partagées entre Dog et Dragon, qui héritent maintenant de la classe Animal.
Dog et Dragon héritent de la classe Animal

Mais qu'est-ce que ça veut dire, "hérite de" ?

Eh bien, très concrètement, lorsque la classe Dog hérite de la classe Animal , toutes les propriétés et méthodes de la classe Animal sont disponibles dans la classe Dog . C'est comme si je les avais écrites dans la classe Dog . Je peux écrire par exemple :

let bob = Dog()
bob.taille = 120
bob.weight = 30
bob.eat()

Les propriétés et méthodes de l'exemple ci-dessus ne sont pas définies dans la classe Dog , mais dans la classe Animal ; et en héritant de cette classe, la classe Dog les récupère. L'héritage, c'est juste ça.

Mettez l'héritage en action

Avant d'aborder l'implémentation de l'héritage, laissez-moi vous donner un exemple d'héritage en iOS. Je vous l'ai dit en introduction, en iOS, tout est objet. Et la plupart d'entre eux utilisent l'héritage !

iOS et l'héritage

C'est notamment très clair pour l'interface graphique. L'interface graphique est pleine de composants. Il peut y avoir des images, des boutons, des labels, etc. Ces composants vont être disposés sur l'interface et ont donc beaucoup de choses en commun : leur taille, leur position, leur couleur, s'ils sont visibles ou non, s'ils réagissent au toucher ou non, et beaucoup d'autres. C'est la raison pour laquelle ils héritent tous d' UIView , une classe qui gère tous ces aspects et permet donc à tous les composants de ne pas avoir à répéter toute cette logique. Il suffit qu'ils en héritent !

Le bus scolaire et l'héritage

Prenons un autre exemple, mais cette fois-ci avec notre bus scolaire. En début de cours, nous avions créé ensemble le diagramme suivant :

Le diagramme que nous avons créé avec nos 3 classes Bus, Road et RoadSection
Notre diagramme de classes

En utilisant l'héritage, nous allons pouvoir modifier ce schéma et rajouter quelques classes :

On ajoute à notre schéma SchoolBus, qui hérite de Bus, ainsi que HomeRoadSection et SchoolRoadSection, qui hérite de RoadSection.
Quelques modifications

Alors, regardons un peu tout cela. Tout d'abord nous allons ajouter la classe SchoolBus . Cette classe hérite de la classe Bus . La classe SchoolBus définit un bus scolaire. La différence avec un bus classique, c'est que le bus scolaire va avoir une propriété en plus : schoolName . Car le bus scolaire est associé à une école. Par ailleurs, la méthode drive de SchoolBus va être légèrement différente de la méthode drive de Bus. Car le bus scolaire va s'arrêter à chaque maison pour récupérer les enfants et ensuite les déposer à l'école, tandis que le bus simple roule seulement sur la route.

Par ailleurs, nous avons deux autres nouvelles classes : HomeRoadSection et SchoolRoadSection , qui héritent toutes les deux de RoadSection . Chacune de ces trois classes va avoir des initialisations différentes qui vont nous permettre de dessiner sur le canevas des sections de route, avec ou sans maison et avec ou sans école. La classe HomeRoadSection a en plus une variable children qui va nous permettre de savoir combien d'enfants le bus va récupérer dans telle maison.

Implémentez l'héritage

Voici venu le moment que vous attendez tous ! Comment fait-on dans le code pour dire qu'une classe hérite d'une autre ? Eh bien, comme pour beaucoup de choses avec Swift, c'est très simple !

Essayons de créer notre classe SchoolBus qui hérite de Bus . Il suffit d'écrire la création de classe comme on a l'habitude de le faire :

class SchoolBus {

}

Et maintenant, pour appliquer l'héritage, on ajoute :  puis la classe dont on veut hériterBus , en l'occurrence) :

class SchoolBus: Bus {
}

Alors que l'implémentation de SchoolBus semble vide, je peux utiliser toutes les propriétés et méthodes de Bus :

var schoolBus = SchoolBus(driverName: "Joe")
schoolBus.seats = 50
schoolBus.drive(road: road)

C'est la beauté de l'héritage. Maintenant je vais rajouter une propriété spécifique à SchoolBus :

class SchoolBus {
   var schoolName = ""
}

La propriété schoolName sera disponible dans la classe SchoolBus , mais pas pour les instances de Bus .

Et voilà ! Je vous l'avais promis, l'héritage avec Swift, c'est simple.

À vous de jouer !

Le contenu de l’exercice se trouve dans le dossier Github P3C1.

  1. Ouvrez un nouveau Playground Xcode.

  2. Copiez le contenu du fichier “main.swift” dans votre Playground.

  3. Suivez les instructions.

En résumé

  • Une classe (dite fille) peut hériter d'une autre classe (dite mère). Dans ce cas, toutes les propriétés et méthodes de la classe mère sont disponibles dans la classe fille, sans que la classe fille ait besoin de les redéfinir.

  • L'héritage permet d'organiser son code grâce à un arbre d'héritage, et d'éviter ainsi des répétitions.

  • Pour qu'une classe hérite d'une autre, on utilise les  :   suivis du nom de la classe mère :

class Daughter: Mother {
}

Vous pouvez être fiers de vous, l’héritage n’est pas une mince affaire mais vous vous en sortez super bien ! On continue ensemble dans le prochain chapitre pour parler des énumérations, et voir comment elles vont nous aider dans notre projet de bus scolaire.

Exemple de certificat de réussite
Exemple de certificat de réussite