2009-07-07 8 views

Répondre

14

Si la classe de base a quelque chose à dire, mais vous voulez qu'il débrayés « à chaque fois », alors j'aurais une paire de méthodes:

public void DoSomething() { 
    //things to do before 
    DoSomethingCore(); 
    //things to do after 
} 
protected abstract void DoSomethingCore(); 
+3

Et vous pourriez avoir voulu mentionner le motif Template Method (ou bien vous avez peut-être tiré pour la brièveté) –

+0

Qu'en est-il du mot clé "virtual" avant la méthode DoSomething? – Kamarey

+1

@Kamarey La méthode DoSomething n'est pas virtuelle: c'est la méthode DoSomethingCore que les sous-classes sont censées remplacer/implémenter. – ChrisW

1

Vous êtes à la recherche d'une méthode virtual (utilisation ce modificateur pour permettre de surcharger la méthode), mais vous ne pouvez pas forcer l'utilisateur à l'écraser. Forcer cela n'a pas de sens si vous avez un corps de toute façon, car on pourrait simplement appeler base.YourMethod() et ne rien faire d'autre, ce qui revient à ne pas surcharger la méthode en premier lieu.

public virtual YourMethod() { 
    // your base class code here 
} 

et la méthode dominante dans une autre classe:

public override YourMethod() { 
    // code to do before the base call 
    base.YourMethod(); 
    // code to do after the base call 
} 
3

Si votre classe de base ne quelque chose dans la méthode, mais vous voulez vous assurer que chaque sous-classe est obligé de mettre en œuvre certaines partie de la méthode, alors vous voulez le Template Method pattern, comme décrit dans la réponse de Marc Gravell.

Il n'existe aucun moyen de fournir une implémentation par défaut dans votre classe de base et forcez toujours les sous-classes à fournir leur propre implémentation. Vous pouvez cependant créer une classe de base abstraite et en hériter pour fournir l'implémentation par défaut, mais rendre cette classe concrète scellée.

public abstract class FooBase { 
    public abstract void DoStuff(); 
} 

public sealed class FooImpl : FooBase { 
    public override void DoStuff { 
     //default widget-munging code 
    } 
} 

Maintenant, toutes les classes qui héritent de FooBase doivent mettre en œuvre DoStuff(), mais vous avez une implémentation par défaut FooImpl à partir de laquelle les sous-classes ne peuvent pas hériter.

Vous pouvez également préférer déléguer la responsabilité de l'implémentation de la méthode à une classe distincte, qui est transmise à la classe de base dans son constructeur. C'est ce qu'on appelle le Strategy pattern.

public sealed class Foo { 
    private IFooStrategy _strategy; 
    public Foo(IStrategy strategy) { 
     _strategy = strategy; 
    } 
    void DoStuff() { 
     _strategy.DoStuff(); 
    } 
    public static IFooStrategy DefaultStrategy { 
     //return singleton instance of the default strategy 
    } 
} 

Maintenant, au lieu de Foo sous-classement, vous créez au lieu de nouvelles implémentations de l'interface IFooStrategy et passer ceux à votre instance Foo. Donc soit vous pouvez faire:

new Foo(Foo.DefaultStrategy); 

ou

new Foo(new DifferentStrategy()); 
1

Sons comme votre implémentation de base ne sera jamais appelé. Pourquoi voudriez-vous fournir une implémentation à laquelle personne ne peut accéder (en sautant à travers les cerceaux sans résister)

Questions connexes