web-dev-qa-db-fra.com

Pourquoi ne sommes-nous pas autorisés à spécifier un constructeur dans une interface?

Duplicata possible:
Interface définissant une signature de constructeur?

Je sais que vous ne pouvez pas spécifier un constructeur dans une interface en .Net, mais pourquoi ne le pouvons-nous pas?

Il serait vraiment utile pour mon projet actuel de pouvoir spécifier qu'un 'moteur' doit être passé avec le constructeur, mais comme je ne peux pas, je dois me contenter d'un commentaire XML sur la classe.

51
Pondidum

Parce qu'une interface décrit le comportement. Les constructeurs ne sont pas un comportement. La façon dont un objet est construit est un détail d'implémentation.

88
cletus

Comment appelleriez-vous le constructeur? Lorsque vous utilisez des interfaces, vous passez normalement une instance de l'interface autour (ou plutôt, une référence). Gardez également à l'esprit que si une classe implémente une interface, une classe dérivée hérite de cette interface, mais peut ne pas avoir le même ensemble de constructeurs.

Maintenant, je peux voir l'utilisation de ce que j'appelle des interfaces statiques pour spécifier les constructeurs et autres membres essentiellement statiques à utiliser dans les méthodes génériques. Voir mon article de blog sur l'idée pour plus d'informations.

28
Jon Skeet

Non, vous ne pouvez pas avoir de constructeurs sur les interfaces pour les raisons qui ont été publiées. Cependant, vous pouvez sur des classes abstraites. Disons par exemple que vous avez cette classe de base.

public abstract class ClassOne
{
    protected int _x;
    protected string _s;

    public ClassOne(int x, string s)
    {
        _x = x;
        _s = s;
    }        
}

Notez qu'il n'y a aucun constructeur qui ne prend aucun argument (constructeur par défaut), ce qui signifie que toute classe qui hérite de ClassOne doit appeler le constructeur qui a 2 arguments.

Ce n'est donc pas valide et ne sera pas compilé.

public class ClassTwo : ClassOne
{
    public ClassTwo() 
    { }
}

Cependant, cela est valide et sera compilé.

public class ClassTwo : ClassOne
{
    public ClassTwo(int x, string s) : base(x, s)
    {  }
}

Je voudrais souligner ici qu'en C #, vous ne pouvez hériter que d'une seule classe de base. Cela signifie que ce n'est peut-être pas la bonne solution pour une situation particulière, mais qu'il faut y réfléchir.

Tony.

9
Tony

Parmi toutes les autres raisons déjà signalées, gardez également à l'esprit que la classe a peut facilement implémenter plusieurs interfaces; quel constructeur utiliser alors?

8
M.Turrini

D'autres réponses ont déjà souligné pourquoi cela n'a pas de sens d'avoir une déclaration constructeur sur une interface. Mais à partir de votre question, je suppose que vous recherchez probablement le modèle d'usine abstrait .

Pour donner un exemple basé sur votre question: vous dites que vous souhaitez en quelque sorte déclarer qu'un "moteur" doit être transmis au constructeur. Vous pouvez le faire en déclarant une interface distincte pour un service de construction comme celui-ci:

public interface IGadgetFactory
{
   IGadget CreateGadget(Engine engine);
}

Tout code qui doit créer des instances IGadget peut alors utiliser une instance IGadgetFactory au lieu d'appeler directement des constructeurs.

6
Wim Coenen

Outre les autres explications données ici, vous devrez de toute façon inventer une nouvelle syntaxe pour les appeler, car si vous avez deux implémentations ou plus à portée sur la ligne:

Dim x as new IDoStuff()

La mise en œuvre de Whice est appelée?

0

Parce que vous ne pouvez pas instancier une interface, un constructeur n'a donc aucun sens.

0
Mork0075