Chargement...

Encapsulation, Héritage et Polymorphisme en C#

Apprenez l’encapsulation, l’héritage et le polymorphisme en C# avec des exemples pour maîtriser les bases de la POO.

La Programmation Orientée Objet (POO / OOP) est une approche développée pour écrire du code réutilisable, maintenable et compréhensible. Les trois piliers fondamentaux de la POO sont :

Lorsque ces trois caractéristiques sont utilisées ensemble, il est possible de construire une architecture solide dans les projets logiciels. Voyons chacune d’elles séparément.


Encapsulation

L’encapsulation cache la structure interne d’une classe au monde extérieur et ne rend accessibles que les parties nécessaires. Ainsi, la manipulation directe des données est empêchée, les erreurs sont réduites et les changements internes n’affectent pas l’extérieur. En C#, elle est mise en œuvre avec des modificateurs d’accès tels que private, protected, internal et public. En général, les champs sont masqués et l’accès contrôlé est fourni via des propriétés ou des méthodes.


public class BankAccount
{
    private decimal _balance; // accès direct interdit

    public decimal Balance 
    { 
        get => _balance; 
        private set => _balance = value; 
    }

    public void Deposit(decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("Le montant doit être supérieur à zéro.");
        Balance += amount;
    }

    public void Withdraw(decimal amount)
    {
        if (amount > Balance)
            throw new InvalidOperationException("Fonds insuffisants.");
        Balance -= amount;
    }
}

Dans cet exemple, le solde (_balance) ne peut pas être modifié directement. L’utilisateur ne peut interagir qu’à travers les méthodes Deposit et Withdraw. Cela empêche une mauvaise utilisation et garantit la sécurité des données.


Héritage

L’héritage permet à une classe d’hériter des propriétés et des comportements d’une autre classe. Ainsi, le code commun est centralisé et devient réutilisable. La classe de base définit les comportements généraux, tandis que les classes dérivées ajoutent des fonctionnalités spécialisées.


public class Animal
{
    public string Name { get; set; } = string.Empty;

    public void Eat()
    {
        Console.WriteLine($"{Name} mange.");
    }
}

public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine($"{Name} aboie.");
    }
}

public class Cat : Animal
{
    public void Meow()
    {
        Console.WriteLine($"{Name} miaule.");
    }
}

class Program
{
    static void Main()
    {
        Dog d = new Dog { Name = "Rex" };
        d.Eat();  // hérité d’Animal
        d.Bark(); // spécifique à Dog

        Cat c = new Cat { Name = "Minou" };
        c.Eat();  // hérité d’Animal
        c.Meow(); // spécifique à Cat
    }
}

Ici, à la fois Dog et Cat héritent de Animal. Le comportement commun Eat() est écrit une seule fois mais est disponible dans toutes les sous-classes.


Polymorphisme

Le polymorphisme signifie que la même méthode peut se comporter différemment selon l’objet. Il existe deux types de polymorphisme :


public class Animal
{
    public string Name { get; set; } = string.Empty;

    public virtual void Speak()
    {
        Console.WriteLine($"{Name} fait un bruit.");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine($"{Name} aboie.");
    }
}

public class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine($"{Name} miaule.");
    }
}

class Program
{
    static void Main()
    {
        Animal a1 = new Dog { Name = "Rex" };
        Animal a2 = new Cat { Name = "Minou" };

        a1.Speak(); // Rex aboie.
        a2.Speak(); // Minou miaule.
    }
}

Le même appel à Speak() produit une sortie différente selon le type de l’objet. Cette flexibilité est l’un des atouts les plus puissants de la POO.


Exemple : Types de livres

Modélisons des livres dans une application de bibliothèque. Les propriétés communes sont définies dans la classe Book, tandis que chaque sous-classe ajoute ses propres informations ou redéfinit la méthode PrintInfo(). De plus, les classes Author et Publisher sont utilisées pour stocker séparément les informations sur l’auteur et l’éditeur. Cela montre comment l’héritage et le polymorphisme peuvent être combinés.


public class Author
{
    public string Name { get; set; } = string.Empty;
    public string Country { get; set; } = string.Empty;
}

public class Publisher
{
    public string Name { get; set; } = string.Empty;
    public string Address { get; set; } = string.Empty;
}

public abstract class Book
{
    public string Title { get; set; } = string.Empty;
    public Author BookAuthor { get; set; } = new Author();
    public Publisher BookPublisher { get; set; } = new Publisher();
    public int Pages { get; set; }
    public string ISBN { get; set; } = string.Empty;
    public int Year { get; set; }

    // À personnaliser dans les sous-classes
    public abstract void PrintInfo();
}

public class ScienceBook : Book
{
    public string Field { get; set; } = string.Empty; // Physique, Chimie, Biologie

    public override void PrintInfo()
    {
        Console.WriteLine($"[Livre scientifique] {Title} - {BookAuthor.Name}, {Pages} pages");
        Console.WriteLine($"Domaine : {Field}, ISBN : {ISBN}, Éditeur : {BookPublisher.Name}");
    }
}

public class HistoryBook : Book
{
    public string Period { get; set; } = string.Empty; // Antiquité, Moyen Âge, etc.

    public override void PrintInfo()
    {
        Console.WriteLine($"[Livre d’histoire] {Title} - {BookAuthor.Name}, {Pages} pages");
        Console.WriteLine($"Période : {Period}, ISBN : {ISBN}, Éditeur : {BookPublisher.Name}");
    }
}

class Program
{
    static void Main()
    {
        var publisher = new Publisher { Name = "Éditions Savoir", Address = "Paris" };
        var author1 = new Author { Name = "Albert Einstein", Country = "Allemagne" };
        var author2 = new Author { Name = "Halil Inalcik", Country = "Turquie" };

        Book b1 = new ScienceBook
        {
            Title = "Théorie de la Relativité",
            BookAuthor = author1,
            BookPublisher = publisher,
            Pages = 250,
            ISBN = "123-456-789",
            Year = 1920,
            Field = "Physique"
        };

        Book b2 = new HistoryBook
        {
            Title = "L’Empire Ottoman",
            BookAuthor = author2,
            BookPublisher = publisher,
            Pages = 500,
            ISBN = "987-654-321",
            Year = 1973,
            Period = "Période Ottomane"
        };

        b1.PrintInfo();
        Console.WriteLine();
        b2.PrintInfo();
    }
}

Avantages


TL;DR

  • Encapsulation : Masque les données internes et fournit un accès contrôlé.
  • Héritage : Les propriétés et comportements de la classe de base sont transmis aux sous-classes.
  • Polymorphisme : La même méthode peut se comporter différemment dans différentes sous-classes.

Articles connexes