Héritage et polymorphisme
Découvrez les principes de la programmation orientée objet, tels que l’héritage, les classes abstraites et le polymorphisme en Scala.
Héritage et polymorphisme est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 2 sur 2. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 2 leçons au total.
Qu'est-ce que l'héritage ?
L'héritage est un concept fondamental de la programmation orientée objet (POO) qui permet à une nouvelle classe d'hériter des propriétés et des comportements (méthodes) d'une classe existante.
Imaginez une relation « parent-enfant ». La classe « enfant » (sous-classe) réutilise le code de la classe « parent » (superclasse), ce qui fait gagner du temps et garantit la cohérence.
- Favorise la réutilisation du code.
- Établit une relation « est un » (par exemple, un Dog est un Animal).
- Aide à organiser le code sous forme de hiérarchie.
Votre première classe de base
Définissons une classe Animal simple. Ce sera notre classe de base, également appelée superclasse ou classe parent. Elle possède un comportement élémentaire : parler.
Exécutez le code pour voir notre animal générique en action !
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
object Main {
def main(args: Array[String]): Unit = {
val myAnimal = new Animal()
myAnimal.speak()
}
}Étendre avec `extends`
Créons maintenant un animal plus spécifique, un Dog. Un Dog est un Animal ; il peut donc hériter de la classe Animal à l'aide du mot-clé extends.
Nous pouvons également redéfinir la méthode speak pour donner à Dog un son qui lui est propre. Remarquez le mot-clé override.
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
class Dog extends Animal {
override val name: String = "Dog"
override def speak(): Unit = {
println(s"$name barks!")
}
}
object Main {
def main(args: Array[String]): Unit = {
val myAnimal = new Animal()
val myDog = new Dog()
myAnimal.speak() // Generic Animal makes a sound.
myDog.speak() // Dog barks!
}
}La puissance de `override`
Le mot-clé override est essentiel en Scala pour plusieurs raisons :
- Clarté : il indique explicitement aux autres développeurs que cette méthode ou ce champ en remplace un autre provenant d'une superclasse.
- Sécurité : le compilateur vérifie que vous redéfinissez réellement un membre existant. Si vous faites une faute de frappe ou si la méthode de la superclasse est modifiée, le compilateur vous en avertit.
- Intention : il indique clairement votre intention de spécialiser ou de modifier un comportement hérité.
Utilisez toujours override lorsque vous redéfinissez des membres hérités !
Polymorphisme : plusieurs formes
Le polymorphisme signifie « plusieurs formes ». En POO, il permet de traiter des objets de classes différentes comme des objets d'une même superclasse.
Vous pouvez ainsi avoir une variable de type Animal contenant un objet Dog, un objet Cat ou toute autre sous-classe de Animal. Lorsque vous appelez une méthode sur cette variable, la méthode correcte correspondant au type réel de l'objet est exécutée.
- Permet d'écrire du code flexible et extensible.
- Fournit une interface unique pour différents types de données.
- Est obtenu grâce à la redéfinition des méthodes.
Le polymorphisme en pratique
Voyons le polymorphisme en action. Nous allons créer une classe Cat semblable à Dog. Nous pourrons ensuite placer différents types d'animaux dans une liste de leur supertype commun, Animal, et appeler leur méthode speak.
Remarquez que chaque animal s'exprime à sa manière, même s'ils sont tous traités comme des types Animal dans la liste.
class Animal {
val name: String = "Generic Animal"
def speak(): Unit = {
println(s"$name makes a sound.")
}
}
class Dog extends Animal {
override val name: String = "Dog"
override def speak(): Unit = {
println(s"$name barks!")
}
}
class Cat extends Animal {
override val name: String = "Cat"
override def speak(): Unit = {
println(s"$name meows!")
}
}
object Main {
def main(args: Array[String]): Unit = {
val animals: List[Animal] = List(
new Animal(),
new Dog(),
new Cat()
)
animals.foreach(_.speak())
}
}Découvrir les classes abstraites
Parfois, vous souhaitez une classe de base qui définit une interface commune, mais qui ne fournit pas d'implémentation complète pour certains de ses membres. C'est là qu'interviennent les classes abstraites.
Une classe abstraite :
- Ne peut pas être instanciée directement (vous ne pouvez pas créer d'objet d'une classe abstraite).
- Peut contenir des méthodes abstraites (sans implémentation) et des méthodes concrètes (avec une implémentation).
- Joue le rôle de modèle que ses sous-classes doivent compléter.
Construire des modèles abstraits
Définissons une abstract class Shape. Toute forme possède une aire, mais la formule de calcul varie selon la forme concernée (cercle, rectangle, etc.).
Nous déclarons donc area comme une méthode abstraite. Remarquez qu'elle n'a pas de corps (pas de = { ... }). Les sous-classes devront fournir son implémentation.
abstract class Shape {
def area: Double // Abstract method, no implementation
def describe(): Unit = {
println("This is a geometric shape.")
}
}
// You cannot do: new Shape() - it's abstract!
object Main {
def main(args: Array[String]): Unit = {
println("Abstract class Shape defined.")
println("Cannot instantiate Shape directly.")
}
}Implémentations concrètes
Créons maintenant des sous-classes concrètes comme Circle et Rectangle, qui étendent notre abstract class Shape. Ces sous-classes doivent fournir une implémentation de la méthode abstraite area.
Elles héritent également de la méthode concrète describe() de Shape.
abstract class Shape {
def area: Double
def describe(): Unit = {
println("This is a geometric shape.")
}
}
class Circle(radius: Double) extends Shape {
override def area: Double = math.Pi * radius * radius
}
class Rectangle(width: Double, height: Double) extends Shape {
override def area: Double = width * height
}
object Main {
def main(args: Array[String]): Unit = {
val circle = new Circle(5)
val rectangle = new Rectangle(4, 6)
println(s"Circle area: ${circle.area}")
circle.describe()
println(s"Rectangle area: ${rectangle.area}")
rectangle.describe()
}
}Vérification : héritage et polymorphisme
Lesquelles des affirmations suivantes concernant l'héritage et le polymorphisme en Scala sont TRUE ?
Récapitulatif : héritage et polymorphisme
Excellent travail ! Dans cette leçon, nous avons étudié les concepts fondamentaux de la POO en Scala :
- Héritage : les sous-classes réutilisent le code et définissent une relation « est un » avec les superclasses à l'aide de
extends. - Mot-clé
override: indispensable pour redéfinir explicitement les méthodes et les champs hérités, tout en garantissant la sécurité des types et la clarté du code. - Polymorphisme : possibilité de traiter les objets de sous-classes différentes comme des objets d'une même superclasse, ce qui permet d'écrire du code flexible et extensible.
- Classes abstraites : modèles qui ne peuvent pas être instanciés directement et qui servent à définir des interfaces communes et des membres abstraits que les sous-classes doivent implémenter.
Ces concepts sont essentiels pour créer des applications Scala bien structurées et faciles à maintenir !
Questions Fréquemment Posées
La leçon « Héritage et polymorphisme » est-elle gratuite ?
Oui — le texte complet de « Héritage et polymorphisme » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 2 leçons au total.
Qu'est-ce que j'apprendrai dans « Héritage et polymorphisme » ?
Découvrez les principes de la programmation orientée objet, tels que l’héritage, les classes abstraites et le polymorphisme en Scala. Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?
Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 2.
Combien de temps prend la leçon « Héritage et polymorphisme » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?
Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Classes, objets et empaquetage
- Héritage et polymorphisme