6 votes

Y a-t-il une raison pour qu'une méthode concrète soit vide dans une classe abstraite ?

J'ai récemment parcouru le code source ouvert de PicketLink. Si vous jetez un coup d'œil à cette classe Dans le cas d'une classe abstraite, vous verrez un certain nombre de méthodes concrètes qui ne font rien. Cela a-t-il une quelconque utilité ?

J'ai pensé à deux choses :

  1. Si la méthode doit être remplacée par des sous-classes et n'est pas définie dans la classe abstraite parente, pourquoi ne pas simplement la rendre abstraite ?
  2. Si seulement certains des classes enfants doivent effectivement implémenter la méthode, cela n'indiquerait-il pas la nécessité d'une restructuration de la hiérarchie des classes afin que les enfants ne soient pas obligés d'avoir des méthodes qui ne sont pas applicables ?

10voto

Andrés Fortier Points 1655

Bien que ce ne soit pas le cas le plus fréquent, il est parfois utile dans le contexte d'une méthode des modèles . Dans ce cas, une méthode définit le flux, laissant la mise en œuvre concrète de certaines parties à ses sous-classes. Dans certains cas, un comportement concret par défaut consiste à ne rien faire, en laissant la méthode concrète de la classe de base vide, mais en permettant une personnalisation dans la sous-classe en la surchargeant.

HTH

5voto

PeteGO Points 1710

Personnellement, je pense qu'il s'agit d'une odeur de code.

Comme vous le dites, à moins qu'elles n'aient une fonctionnalité de base - ce qui n'est pas le cas -, elles devraient être abstraites, obligeant les classes dérivées à fournir une implémentation.

Si certaines classes dérivées n'ont pas d'implémentation pour ces méthodes, il y a probablement quelque chose qui ne va pas dans la conception.

Considérez ceci :

public abstract class Animal
{
    public abstract string Speak();
}

public class Dog : Animal
{
    public override string Speak()
    {
        Console.WriteLine("Woof");
    }
}

public class Cat : Animal
{
    public override string Speak()
    {
        Console.WriteLine("Meow");
    }
}

Tout va bien jusqu'à présent, mais que se passe-t-il si vous voulez ajouter un animal qui ne parle pas ?

public class Ant : Animal
{
    public override string Speak()
    {
        // do nothing - ants don't speak.
    }
}

À mon avis, c'est une mauvaise chose. Quelqu'un pourrait faire cela (ce que vous avez décrit).

public abstract class Animal
{
    public string Speak()
    {
        // not abstract because not all derived animals speak.
    }
}

À mon avis, c'est mieux, mais ce n'est pas encore génial. Ce que j'aimerais voir dans cette situation, c'est que Speak soit déplacé vers une interface et que seuls les animaux qui peuvent parler l'implémentent, ou quelque chose comme ça.

public abstract class Animal
{
}

public abstract class Mammal : Animal
{
    public abstract string Speak();
}

public class Dog : Mammal
{
    public override string Speak()
    {
        Console.WriteLine("Woof");
    }
}

public class Cat : Mammal
{
    public override string Speak()
    {
        Console.WriteLine("Meow");
    }
}

public class Ant : Animal
{
}

4voto

Tom G Points 5727

En s'appuyant sur la réponse d'Andres Fortier, vous verrez également ce modèle dans Swing, avec les différentes classes d'adaptateurs d'écouteurs d'événements (EventListener Adapter). Par exemple, Adaptateur de souris fournit des méthodes vides correspondantes pour chaque méthode d'écoute. Cela permet à l'interface de définir toutes les méthodes pertinentes, mais aux implémentations d'étendre l'adaptateur correspondant et de ne surcharger qu'une seule méthode qui les intéresse, au lieu d'être obligées de fournir des corps vides pour toutes les autres méthodes de l'interface.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X