2009-04-02 4 views

Répondre

2

J'ai également rencontré cela. ce qui est 'pire', selon la façon dont vous le regardez, c'est que vous ne pouvez pas définir les implémentations d'interface comme étant virtuelles à surcharger dans les classes descendantes. J'ai pris l'habitude de le faire:

public class Foo:IFoo 
{  
    void IFoo.DoA() 
    { 
      DoACore(); 
    } 
    void IFoo.DoB() 
    { 
      DoBCore(); 
    } 
    protected virtual void DoACore() 
    { 
    } 
    protected virtual void DoBCore() 
    { 
    } 
} 
public class Bar:Foo 
{  protected override void DoACore() 
     { 
      base.DoACore(); 
     } 
     protected override void DoBCore() 
     { 
      base.DoBCore(); 
     } 
} 
+0

Très bien, proche de ce que je veux ... où est le skeet de Jon? –

+0

+1, vous devriez accepte cette réponse C'est la pratique "standard" dans .Net pour gérer l'implémentation de l'interface dans les arbres d'héritage profond –

+0

Certainement ... J'aime cette solution .... Michael es-tu la même personne que n8wrl, essaie d'obtenir des votes de déménagement :)? –

3
public class Bar : Foo, IFoo 
{ 
    // Your code 
} 
+0

Pourquoi IFoo est-il nécessaire? pourquoi -1? –

+0

Je suppose -1 parce que les gens le considèrent comme évident ... En ajoutant IFoo, vous dites que Bar a sa propre implémentation, différente de l'implémentation de Foo. C'est le but d'être explicite. L'implentation explicite de Foo reste avec Foo. – Ruslan

+0

Ruslan droite, mais -1 n'est pas le mien ;-) – alex2k8

2

Voir n8wrl's answer à la façon dont vous devriez faire cela. Voir ci-dessous pour la raison pourquoi.

Vous ne pouvez pas explicitement implémenter des membres d'interface (void IFoo.DoA()) lors de la mise en œuvre implicite de l'interface. En d'autres termes, étant donné que Bar implémente uniquement IFoo en raison de l'extension Foo, vous ne pouvez pas utiliser une implémentation explicite.

Cela fonctionne:

public class Bar : Foo 
{ 
    public void DoA() 
    { 
     ... 
    } 

    public void DoB() 
    { 
     ... 
    } 

Ou ceci:

public class Bar : Foo, IFoo 
{ 
    void IFoo.DoA() 
    { 
     ... 
    } 

    void IFoo.DoB() 
    { 
     ... 
    } 

Un plus grand problème que vous aurez probablement faire face est que, puisque Foo n'est pas abstraite, elle doit mettre en œuvre DoA et DoB. Si vous également implémenter ces méthodes dans la barre, vous ne le ferez pas polymorphiquement. Vous serez hiding les implémentations Foo si le code a un handle au type Bar.

+0

base.doA(); donne une erreur :) –

+0

droite, c'est pourquoi je l'ai commenté. C'est un problème distinct. Premièrement, il n'y a pas d'implémentation de doA dans la base, et deuxièmement, si vous voulez dire DoA, car elle est explicitement implémentée, elle n'est pas visible à moins de lancer la base à IFoo ... –

+0

Efen si vous jetez la base à IFoo, elle n'est pas visible car le compilateur Impossible de déterminer quel IFoo utiliser (puisque les deux classes implémentent IFoo, et comme je l'ai dit dans la réponse, ce n'est pas polymorphe.) –

1

Je soupçonne que la confusion se pose sur la façon dont les interfaces ont été mises en œuvre en C++, comme des classes abstraites et l'héritage multiple.

Dans .NET, et interface est simplement un contrat qui dit que vous allez implémenter ces méthodes.

Vous écrivez du code ne compilera pas pour la même raison ce code compile l'habitude (ce serait avec C++):

public interface IFoo 
{ 
    void DoSomething(); 
} 

public abstract class Foo : IFoo 
{ 
} 

Foo Foo déclarant que implémente IFoo, il ne dit rien d'autre au sujet n'importe qui.

Si vous vouliez forcer les classes dérivées à mettre en œuvre que vous feriez:

public interface IFoo 
{ 
    void DoSomething(); 
} 

public abstract class Foo : IFoo 
{ 
    public abstract void DoSomething(); 
} 

Ou si vous voulez vraiment les méthodes d'interface cachées par la mise en œuvre explicite, alors quelque chose comme n8wrl affiché ci-dessus.

+0

sorte de non pertinent, mais merci pour votre temps de toute façon! –

+0

Désolé que vous le pensiez ... Je pensais que le problème que vous aviez était que dans les méthodes d'interface .NET ne sont pas automatiquement virtuel comme ils sont en C++. –

1

Au début, ce n'est pas clair quelle est la tâche? Si les objectifs étaient de résoudre un problème dès que possible, 'Bar: Foo, IFoo' est la solution la plus courte.

Si vous essayez simplement d'apprendre la différence d'interfaces 'implicite/explicite', vérifiez ceci post.

Notez également que la solution 'n8wrl' est discutable. C'est correct seulement si Foo a effectivement besoin d'implémenter IFoo explicitement. Si non, il y a une manière plus simple:

Espérons que cela aide.

+0

@Sasha, je viens de remarquer que le post suggéré est votre question :-) – alex2k8

+0

@ alex2k8, la solution de n8wrl fonctionne en effet pour moi. THX –

Questions connexes