Passer au contenu du pied de page
Iron Academy Logo
Apprendre le C#
Apprendre le C#

Autres catégories

Comprendre la classe abstraite C#

Tim Corey
19m 59s

Les classes abstraites en C# sont un concept fondamental qui suscite souvent des interrogations chez les développeurs. Dans sa vidéo "C# Abstract Classes - What They Are, How to Use Them, and Best Practices", Tim Corey explique ce que sont les classes abstraites, comment les utiliser et quelles sont les meilleures pratiques. Cet article résume les points clés de cette vidéo, en utilisant les horodatages comme référence.

Introduction

Tim (0:00) explique que les classes abstraites sont souvent remises en question en termes d'objectif, de fonctionnalité et d'importance. Il décrit une classe abstraite comme un mélange entre une classe de base complète et une interface, située entre les deux en termes de fonctionnalité.

Démonstration d'une application

À (0:59), Tim présente une application de démonstration pour montrer les classes abstraites. L'application comprend une application console et une bibliothèque de classes avec deux classes d'accès aux données qui simulent des opérations de base de données. Ces classes possèdent des méthodes de chargement et d'enregistrement des données, que Tim utilise pour illustrer les similitudes et les différences entre les classes abstraites, les classes de base et les interfaces.

Voici le code initial de la classe de base et des classes dérivées :

// Base Class Definition
public class DataAccess
{
    // Method to load the connection string
    public string LoadConnectionString()
    {
        Console.WriteLine("Loading the connection string...");
        return "Test Connection String";
    }

    // Method to load data
    public void LoadData()
    {
        Console.WriteLine("Loading data...");
    }

    // Method to save data
    public void SaveData()
    {
        Console.WriteLine("Saving data...");
    }
}

// Derived class that inherits from DataAccess
public class SQLDataAccess : DataAccess
{
    // Overriding LoadData method to specify SQL data loading
    public new void LoadData()
    {
        Console.WriteLine("Loading SQL data...");
    }

    // Overriding SaveData method to specify SQL data saving
    public new void SaveData()
    {
        Console.WriteLine("Saving SQL data...");
    }
}

// Derived class that inherits from DataAccess
public class SQLiteDataAccess : DataAccess
{
    // Overriding LoadData method to specify SQLite data loading
    public new void LoadData()
    {
        Console.WriteLine("Loading SQLite data...");
    }

    // Overriding SaveData method to specify SQLite data saving
    public new void SaveData()
    {
        Console.WriteLine("Saving SQLite data...");
    }
}
// Base Class Definition
public class DataAccess
{
    // Method to load the connection string
    public string LoadConnectionString()
    {
        Console.WriteLine("Loading the connection string...");
        return "Test Connection String";
    }

    // Method to load data
    public void LoadData()
    {
        Console.WriteLine("Loading data...");
    }

    // Method to save data
    public void SaveData()
    {
        Console.WriteLine("Saving data...");
    }
}

// Derived class that inherits from DataAccess
public class SQLDataAccess : DataAccess
{
    // Overriding LoadData method to specify SQL data loading
    public new void LoadData()
    {
        Console.WriteLine("Loading SQL data...");
    }

    // Overriding SaveData method to specify SQL data saving
    public new void SaveData()
    {
        Console.WriteLine("Saving SQL data...");
    }
}

// Derived class that inherits from DataAccess
public class SQLiteDataAccess : DataAccess
{
    // Overriding LoadData method to specify SQLite data loading
    public new void LoadData()
    {
        Console.WriteLine("Loading SQLite data...");
    }

    // Overriding SaveData method to specify SQLite data saving
    public new void SaveData()
    {
        Console.WriteLine("Saving SQLite data...");
    }
}

Création d'une classe de base

Tim explique (3:21) comment créer une classe de base. Il refactorise le code pour déplacer les méthodes communes, telles que LoadConnectionString, dans une classe de base appelée DataAccess. En héritant de cette classe de base, d'autres classes comme SQLDataAccess et SQLiteDataAccess accèdent à ces méthodes partagées, réduisant la duplication de code.

Rendre la classe de base abstraite

Tim, à (5:56), transforme la classe de base en classe abstraite pour démontrer les différences. Il change DataAccess en une classe abstraite, l'empêchant d'être instanciée directement. Au lieu de cela, seules les classes qui héritent de cette classe abstraite, telles que SQLiteDataAccess et SQLDataAccess, peuvent implémenter ses méthodes et utiliser sa fonctionnalité partagée.

Voici comment le code change lorsque DataAccess devient une classe abstraite :

// Abstract Base Class Definition
public abstract class AbstractDataAccess
{
    // Shared method to load connection string
    public string LoadConnectionString()
    {
        Console.WriteLine("Loading the connection string...");
        return "Test Connection String";
    }

    // Abstract methods that must be implemented by derived classes
    public abstract void LoadData();
    public abstract void SaveData();
}
// Abstract Base Class Definition
public abstract class AbstractDataAccess
{
    // Shared method to load connection string
    public string LoadConnectionString()
    {
        Console.WriteLine("Loading the connection string...");
        return "Test Connection String";
    }

    // Abstract methods that must be implemented by derived classes
    public abstract void LoadData();
    public abstract void SaveData();
}

Portion d'interface dans la classe abstraite

Tim (8:34) explique comment les classes abstraites combinent les caractéristiques des interfaces et des classes de base. Il déclare des méthodes abstraites au sein de la classe abstraite, telles que public abstract void LoadData(); et public abstract void SaveData();, sans les implémenter. Cela garantit que toute classe dérivée doit implémenter ces méthodes, de manière similaire au fonctionnement des interfaces.

Surmonter les méthodes dans les classes abstraites

Tim (12:56) explique comment remplacer des méthodes dans une classe abstraite. Il montre que vous pouvez déclarer une méthode dans la classe de base comme virtual, permettant aux classes dérivées de la remplacer. Cette approche offre une certaine flexibilité dans la manière dont les méthodes sont mises en œuvre et étendues dans les classes dérivées.

Voici le code de la classe dérivée montrant les substitutions de méthodes :

// Derived class from abstract base class
public class SQLDataAccessWithAbstract : AbstractDataAccess
{
    // Implementing the abstract LoadData method
    public override void LoadData()
    {
        Console.WriteLine("Loading SQL data...");
    }

    // Implementing the abstract SaveData method
    public override void SaveData()
    {
        Console.WriteLine("Saving SQL data...");
    }
}
// Derived class from abstract base class
public class SQLDataAccessWithAbstract : AbstractDataAccess
{
    // Implementing the abstract LoadData method
    public override void LoadData()
    {
        Console.WriteLine("Loading SQL data...");
    }

    // Implementing the abstract SaveData method
    public override void SaveData()
    {
        Console.WriteLine("Saving SQL data...");
    }
}

Quand utiliser les classes abstraites

Tim (16:01) indique que les classes abstraites ne doivent pas être utilisées tous les jours, mais qu'elles sont utiles dans des scénarios spécifiques. Il met en garde contre l'utilisation de classes abstraites simplement parce que deux classes partagent un code similaire. Il insiste plutôt sur le maintien de la relation "est un" et suggère d'envisager des méthodes ou des classes d'aide pour le code partagé, le cas échéant.

Voici le code du programme principal qui en démontre l'utilisation :

// Main Program
class Program
{
    static void Main(string[] args)
    {
        // Using Base Class
        SQLDataAccess sqlData = new SQLDataAccess();
        Console.WriteLine(sqlData.LoadConnectionString());
        sqlData.LoadData();
        sqlData.SaveData();

        Console.WriteLine("--------------------------");

        // Using Derived Class from Abstract Base Class
        SQLDataAccessWithAbstract sqlDataAbstract = new SQLDataAccessWithAbstract();
        Console.WriteLine(sqlDataAbstract.LoadConnectionString());
        sqlDataAbstract.LoadData();
        sqlDataAbstract.SaveData();

        Console.WriteLine("--------------------------");

        // You can't instantiate Abstract Base Class directly
        // AbstractDataAccess abstractData = new AbstractDataAccess(); 
        // Error: Cannot create an instance of the abstract class
    }
}
// Main Program
class Program
{
    static void Main(string[] args)
    {
        // Using Base Class
        SQLDataAccess sqlData = new SQLDataAccess();
        Console.WriteLine(sqlData.LoadConnectionString());
        sqlData.LoadData();
        sqlData.SaveData();

        Console.WriteLine("--------------------------");

        // Using Derived Class from Abstract Base Class
        SQLDataAccessWithAbstract sqlDataAbstract = new SQLDataAccessWithAbstract();
        Console.WriteLine(sqlDataAbstract.LoadConnectionString());
        sqlDataAbstract.LoadData();
        sqlDataAbstract.SaveData();

        Console.WriteLine("--------------------------");

        // You can't instantiate Abstract Base Class directly
        // AbstractDataAccess abstractData = new AbstractDataAccess(); 
        // Error: Cannot create an instance of the abstract class
    }
}

Conclusion

La plongée profonde de Tim Corey dans les classes abstraites C# offre une compréhension claire et pratique de leur objectif, de leur fonctionnalité et de leurs applications dans le monde réel. À travers son application de démonstration, il montre comment les classes abstraites comblent le fossé entre les classes de base et les interfaces, ce qui permet aux développeurs de créer des structures de code flexibles et faciles à maintenir.

En mettant l'accent sur les meilleures pratiques, telles que l'utilisation de classes abstraites dans les bons scénarios et l'absence de surutilisation, Tim fournit aux développeurs les outils nécessaires pour faire des choix de conception éclairés. Avec une solide maîtrise de ces concepts, les développeurs peuvent améliorer leurs compétences en programmation orientée objet et créer des applications C# robustes.

Hero Worlddot related to Comprendre la classe abstraite C#
Hero Affiliate related to Comprendre la classe abstraite C#

Gagnez plus en partageant ce que vous aimez

Vous créez du contenu pour les développeurs travaillant avec .NET, C#, Java, Python ou Node.js ? Transformez votre expertise en revenu supplémentaire !

Équipe de soutien Iron

Nous sommes en ligne 24 heures sur 24, 5 jours sur 7.
Chat
Email
Appelez-moi