Maîtriser l’Héritage en Dart : Avantages, Limites et Bonnes Pratiques
Maîtriser l’Héritage en Dart : Avantages, Limites et Bonnes Pratiques
Objectifs du cours
- À l’issue de ce cours, vous serez en mesure de :
- Comprendre le concept d’héritage en Dart
- Utiliser l’héritage pour créer des classes dérivées
- Utiliser l’héritage pour réutiliser le code
-
Introduction à l’Héritage en Dart
- L’héritage est un mécanisme de programmation qui permet à une classe de tirer parti des propriétés et des méthodes d’une autre classe. En Dart, l’héritage est limité à une seule classe par classe.
-
Définition de l’Héritage :
- L’héritage est l’un des principes fondamentaux de la programmation orientée objet (POO) qui permet à une classe (appelée sous-classe ou classe dérivée) d’hériter des caractéristiques (attributs et méthodes) d’une autre classe (appelée superclasse ou classe de base). En Dart, l’héritage est réalisé à l’aide du mot-clé extends.
-
Avantages de l’Héritage :
- Réutilisation du Code :L’héritage permet de réutiliser le code déjà présent dans une classe de base, évitant ainsi la redondance et favorisant la modularité.
- Modélisation Hiérarchique : Il facilite la modélisation hiérarchique des entités du monde réel, ce qui rend le code plus intuitif et reflète mieux la structure de la réalité.
- Maintenance Facilitée : Les modifications apportées à la classe de base se répercutent automatiquement sur toutes les classes dérivées, facilitant ainsi la maintenance du code.
- Extension de Fonctionnalités : Les classes dérivées peuvent étendre les fonctionnalités de la classe de base en ajoutant de nouvelles méthodes ou en modifiant le comportement existant.
-
Limites de l’Héritage :
- Fragilité du Code : Les modifications dans la classe de base peuvent potentiellement affecter toutes les classes dérivées, introduisant ainsi un risque de fragilité du code.
- Rigidité du Code : L’héritage peut rendre le code rigide, car les changements dans la hiérarchie des classes peuvent être difficiles à mettre en œuvre sans casser le code existant.
- Dépendance Forte : Les classes dérivées sont fortement liées à la classe de base, ce qui peut entraîner une dépendance complexe entre les différentes parties du programme.
- Confusion dans la Hiérarchie : Une hiérarchie trop profonde ou complexe peut rendre le code difficile à comprendre et à maintenir.
-
Utilisation de l’Héritage en Dart
-
Déclaration d’une Classe Dérivée en Dart
- La déclaration d’une classe dérivée en Dart se fait avec le mot-clé
extends
. Cela indique que la nouvelle classe hérite des caractéristiques de la classe parente. - L’utilisation de l’héritage en Dart permet de créer des relations entre les classes, favorisant la réutilisation du code et la structuration logique des entités dans une application.
-
Exemple :
- Considérons une classe Véhicule comme classe de base avec des propriétés communes comme marque et année. Une classe dérivée, Voiture, peut hériter de Véhicule et ajouter des propriétés spécifiques comme nombreDePortes.
- Dans cet exemple, la classe de base Vehicule a deux propriétés, marque et annee, ainsi qu’une méthode afficherDetails() qui affiche les détails du véhicule.
- La classe dérivée Voiture ajoute une nouvelle propriété nombreDePortes et une méthode afficherDetailsVoiture() qui appelle la méthode de la classe de base et affiche également le nombre de portes spécifique à la voiture.
-
Activités :
- Créez une classe Véhicule avec des propriétés et des méthodes de base.
- Définissez une classe Voiture qui étend Véhicule.
- Créez des instances de Voiture et accédez aux propriétés de la classe parente.
-
Exercice :
- Ajoutez une autre classe dérivée, par exemple Moto, qui hérite également de Véhicule.
- Implémentez des méthodes spécifiques dans les classes dérivées.
-
Utilisation des Propriétés et des Méthodes de la Classe Parente en Dart
- Les classes dérivées peuvent utiliser les propriétés et les méthodes de la classe parente, permettant une extension ou une modification du comportement existant.
-
Activités :
- Appelez les méthodes de la classe parente à partir de la classe dérivée.
- Accédez aux propriétés de la classe parente depuis la classe dérivée.
-
Exercices :
- Modifiez le comportement d’une méthode de la classe dérivée en utilisant une méthode de la classe parente.
- Ajoutez une propriété à la classe dérivée qui utilise la valeur d’une propriété de la classe parente.
-
Surcharge des Méthodes en Dart
- La surcharge des méthodes en Dart permet à une classe dérivée de fournir une implémentation spécifique d’une méthode déjà définie dans la classe parente.
-
Activités :
- Créez une classe parente avec une méthode à surcharger.
- Déclarez une classe dérivée et surchargez la méthode.
-
Exercices :
- Ajoutez un paramètre à la méthode de la classe parente dans la surcharge.
- Appelez la méthode de la classe parente à partir de la classe dérivée.
-
App01
-
Applications
-
App01
- Créez une classe Person qui représente une personne. La classe Person doit avoir les propriétés suivantes :
- name : le nom de la personne
- age : l’âge de la personne
- Créez une classe dérivée Employee qui hérite de la classe Person. La classe Employee doit avoir la propriété suivante :
- jobTitle : le titre de poste de l’employé
- Créez un objet de la classe Employee et affichez ses propriétés.
-
App02
- Créez une classe Animal qui représente un animal. La classe Animal doit avoir les propriétés suivantes :
- name : le nom de l’animal
- Créez une classe dérivée Vertebrate qui hérite de la classe Animal. La classe Vertebrate doit avoir la propriété suivante :
- hasBones : un booléen qui indique si l’animal a des os
- Créez une classe dérivée Mammal qui hérite de la classe Vertebrate. La classe Mammal doit avoir la propriété suivante :
- givesBirth : un booléen qui indique si l’animal donne naissance à des petits vivants
- Créez une classe dérivée Dog qui hérite de la classe Mammal.
- Créez un objet de la classe Dog et affichez ses propriétés.
-
App03
// Classe de base
class Vehicule {
String marque;
int annee;
// Constructeur de la classe de base
Vehicule(this.marque, this.annee);
// Méthode de la classe de base
void afficherDetails() {
print('Marque: $marque');
print('Année: $annee');
}
}
// Classe dérivée
class Voiture extends Vehicule {
int nombreDePortes;
// Constructeur de la classe dérivée
Voiture(String marque, int annee, this.nombreDePortes)
: super(marque, annee); // Appel du constructeur de la classe de base
// Méthode de la classe dérivée
void afficherDetailsVoiture() {
afficherDetails(); // Appel de la méthode de la classe de base
print('Nombre de portes: $nombreDePortes');
}
}
void main() {
// Utilisation des classes
var maVoiture = Voiture('Toyota', 2022, 4);
maVoiture.afficherDetailsVoiture();
}
Solution
// Classe de base
class Vehicule {
String marque;
int annee;
// Constructeur de la classe de base
Vehicule(this.marque, this.annee);
// Méthode de la classe de base
void afficherDetails() {
print('Marque: $marque');
print('Année: $annee');
}
}
// Classe dérivée
class Voiture extends Vehicule {
int nombreDePortes;
// Constructeur de la classe dérivée
Voiture(String marque, int annee, this.nombreDePortes)
: super(marque, annee); // Appel du constructeur de la classe de base
// Méthode de la classe dérivée
void afficherDetailsVoiture() {
afficherDetails(); // Appel de la méthode de la classe de base
print('Nombre de portes: $nombreDePortes');
}
}
void main() {
// Utilisation des classes
var maVoiture = Voiture('Toyota', 2022, 4);
maVoiture.afficherDetailsVoiture();
}
Solution
// Classe de base
class Vehicule {
String marque;
int annee;
// Constructeur de la classe de base
Vehicule(this.marque, this.annee);
// Méthode de la classe de base
void afficherDetails() {
print('Marque: $marque');
print('Année: $annee');
}
}
// Classe dérivée Voiture
class Voiture extends Vehicule {
int nombreDePortes;
// Constructeur de la classe dérivée
Voiture(String marque, int annee, this.nombreDePortes)
: super(marque, annee); // Appel du constructeur de la classe de base
// Méthode de la classe dérivée
void afficherDetailsVoiture() {
afficherDetails(); // Appel de la méthode de la classe de base
print('Nombre de portes: $nombreDePortes');
}
}
// Classe dérivée Moto
class Moto extends Vehicule {
String typeMoto;
// Constructeur de la classe dérivée
Moto(String marque, int annee, this.typeMoto)
: super(marque, annee); // Appel du constructeur de la classe de base
// Méthode de la classe dérivée
void afficherDetailsMoto() {
afficherDetails(); // Appel de la méthode de la classe de base
print('Type de moto: $typeMoto');
}
}
void main() {
// Utilisation des classes
var maVoiture = Voiture('Toyota', 2022, 4);
maVoiture.afficherDetailsVoiture();
print('\n'); // Saut de ligne pour la clarté
var maMoto = Moto('Harley-Davidson', 2021, 'Cruiser');
maMoto.afficherDetailsMoto();
}
class Animal {
String nom;
Animal(this.nom);
void faireDuBruit() {
print('Certains animaux font du bruit.');
}
}
class Chien extends Animal {
Chien(String nom) : super(nom);
void faireUnBruitPersonnalise() {
faireDuBruit(); // Utilisation de la méthode de la classe parente
print('$nom aboie fort !');
}
}
class Forme {
void dessiner() {
print('Dessiner une forme générique.');
}
}
class Cercle extends Forme {
@override
void dessiner() {
print('Dessiner un cercle.');
}
}
Solution
class Person {
String name;
int age;
Person(this.name, this.age);
}
class Employee extends Person {
String jobTitle;
Employee(String name, int age, this.jobTitle) : super(name, age);
}
void main() {
// Création d'un objet de la classe Employee
Employee employee = Employee("John Doe", 30, "Software Engineer");
// Affichage des propriétés de l'objet
print(employee.name); // John Doe
print(employee.age); // 30
print(employee.jobTitle); // Software Engineer
}
Solution
class Animal {
String name;
Animal(this.name);
}
class Vertebrate extends Animal {
bool hasBones;
Vertebrate(String name, this.hasBones) : super(name);
}
class Mammal extends Vertebrate {
bool givesBirth;
Mammal(String name, bool hasBones, this.givesBirth) : super(name, hasBones);
}
class Dog extends Mammal {
Dog(String name, bool hasBones, bool givesBirth) : super(name, hasBones, givesBirth);
}
void main() {
// Création d'un objet de la classe Dog
Dog dog = Dog("Rex", true, true);
// Affichage des propriétés de l'objet
print(dog.name); // Rex
print(dog.hasBones); // true
print(dog.givesBirth); // true
}
Solution