2010-07-11 8 views
8

J'ai une interface pour que les auteurs de classe soient forcés d'implémenter certaines méthodes. Je veux également autoriser certaines méthodes implémentées par défaut, donc je crée une classe abstraite. Le problème est que toutes les classes héritent de la classe de base, j'ai donc quelques fonctions d'aide là-dedans.La classe abstraite n'implémente pas l'interface

J'ai essayé d'écrire: IClass avec la base abstraite mais j'ai eu une erreur que la base n'a pas implémenté l'interface. Bien sur parce que je veux ce résumé et que les utilisateurs implémentent ces méthodes. En tant qu'objet de retour, si j'utilise la base, je ne peux pas appeler les méthodes de classe d'interface. Si j'utilise l'interface, je ne peux pas accéder aux méthodes de base.

Comment faire pour que je puisse avoir ces classes auxiliaires et forcer les utilisateurs à implémenter certaines méthodes?

Répondre

6

Déplacez les méthodes d'interface dans la classe abstraite et déclarez-les également abstraites. De ce fait, les classes dérivantes sont obligées de les implémenter. Si vous voulez un comportement par défaut, utilisez des classes abstraites, si vous voulez seulement avoir la signature corrigée, utilisez une interface. Les deux concepts ne se mélangent pas.

15

Assurez-vous que les méthodes de la classe de base portent le même nom que l'interface et qu'elles sont publiques. En outre, rendez-les virtuels afin que les sous-classes puissent les remplacer sans les cacher.

interface IInterface { 
    void Do(); 
    void Go(); 
} 

abstract class ClassBase : IInterface { 

    public virtual void Do() { 
     // Default behaviour 
    } 

    public abstract void Go(); // No default behaviour 

} 

class ConcreteClass : ClassBase { 

    public override void Do() { 
     // Specialised behaviour 
    } 

    public override void Go() { 
     // ... 
    } 

} 
0

Ayant rencontré le même problème récemment, j'ai trouvé une solution un peu plus élégante (à mon avis). Il ressemble à:

public interface IInterface 
{ 
    void CommonMethod(); 
    void SpecificMethod(); 
} 

public abstract class CommonImpl 
{ 
    public void CommonMethod() // note: it isn't even virtual here! 
    { 
     Console.WriteLine("CommonImpl.CommonMethod()"); 
    } 
} 

public class Concrete : CommonImpl, IInterface 
{ 
    void SpecificMethod() 
    { 
     Console.WriteLine("Concrete.SpecificMethod()"); 
    } 
} 

maintenant, selon C# spec (. 13.4.4 mapping Interface), dans le processus de cartographie IInterface sur Concrete classe, compilateur recherchera pour CommonMethod en CommonImpl aussi, et il n » Il faut même être virtuel dans la classe de base!

L'autre avantage significatif, comparé à la solution de Mau, est que vous n'avez pas besoin de lister chaque membre de l'interface dans la classe de base abstraite.

+0

Je préfère la solution de Mau. C'est explicite et faites que le compilateur fasse le travail de conformité pour vous. Dans cette solution, vous pouvez oublier d'ajouter la IInterface à la classe dérivée. – PlayTank

+0

@PlayTank: ... et finalement il va échouer sur une conversion implicite, aussi au moment de la compilation. Bien que je sois d'accord, la solution manque de rigueur articulée. – vines

Questions connexes