web-dev-qa-db-fra.com

Constructeur abstrait en C #

Dupliquer possible:
Pourquoi ne puis-je pas créer un constructeur abstrait sur une classe abstraite C #?

Pourquoi je ne peux pas déclarer abstrait un constructeur de ma classe comme ceci:

public abstract class MyClass {
    public abstract MyClass(int param);
}
43
AndreyAkinshin

Les constructeurs ne sont applicables qu'à la classe dans laquelle ils sont définis, c'est-à-dire qu'ils ne sont pas hérités. Les constructeurs de classes de base sont utilisés (vous devez appeler l'un d'eux, même si vous appelez uniquement celui par défaut) mais ne sont pas remplacés par les classes dérivées. Vous pouvez définir un constructeur sur une classe de base abstraite. Il ne peut pas être utilisé directement, mais peut être appelé en dérivant des classes. Ce que vous ne pouvez pas faire, c'est forcer une classe dérivée à implémenter une signature de constructeur spécifique.

Il est parfaitement raisonnable de définir un constructeur, généralement protégé, afin de définir un code de configuration commun pour toutes les classes dérivées. Cela est particulièrement vrai, peut-être, lorsque la classe abstraite fournit un autre comportement par défaut qui repose sur cette configuration. Par exemple:

public abstract class Foo
{
     public string Name { get; private set; }

     protected Foo( string name )
     {
         this.Name = name;
     }
}

public class Bar : Foo
{
     public Bar() : base("bar")
     {
        ...
     }
}
68
tvanfosson

Vous ne pouvez pas le déclarer abstract, mais vous pouvez avoir un constructeur sur votre classe abstraite; Il suffit de supprimer Word abstract et de lui fournir un corps.

12
Zach Johnson

Les constructeurs sont plus proches des méthodes statiques que des méthodes "régulières". Comme les méthodes statiques, elles peuvent être surchargées _, mais pas surchargées_. Autrement dit, ils ne sont pas hérités mais peuvent être redéfinis. 

public BaseClass
{
   public BaseClass( String s ) { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass extends BaseClass
{
   public SubClass( String s )  { ... }
   public static void doIt ( String s ) { ... }
}

public SubClass2 extends BaseClass
{
}

new SubClass( "hello" );
SubClass.doIt( "hello" ); 

new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK

Les constructeurs et les méthodes statiques sont jamais distribués dynamiquement (virtuellement) - Vous connaissez toujours le type concret que vous instanciez ou la classe concrète de la méthode statique. C'est pourquoi cela n'a aucun sens d'avoir constructeur abstrait et méthode statique abstraite. C'est pourquoi vous ne pouvez pas non plus spécifier de constructeur ni de méthode statique dans interfaces.

Vous pouvez même considérer le constructeur comme étant méthode d'usine statique} (et voir le motif correspondant ):

  MyClass obj = new MyClass(); // the way it is
  MyClass obj = MyClass.new(); // think of it like this

Le seul cas où je vois où il serait judicieux de définir un constructeur abstrait ou une méthode statique abstraite serait si réflexion est utilisé. Dans ce cas, vous pouvez vous assurer que toutes les sous-classes redéfiniront la méthode statique ou le constructeur correspondant. Mais la réflexion est un autre sujet ...

Note: dans des langages tels que Smalltalk, où les classes sont des objets normaux, vous pouvez remplacer la méthode statique et avoir un constructeur abstrait. Mais cela ne s'applique pas à Java car les classes ne sont pas des objets "normaux", même si vous pouvez les obtenir avec réflexion.

6
ewernli

Abstrait implique virtuel. Un constructeur autre que celui par défaut ne peut jamais être appelé de manière polymorphe. Par conséquent, les constructeurs virtuels et abstraits ne sont pas autorisés.

Si, dans une future version de C #, les génériques sont améliorés pour permettre l’appel de constructeurs autres que ceux par défaut via un paramètre de type générique, des appels polymorphes aux constructeurs sont possibles et des constructeurs virtuels et abstraits peuvent également être ajoutés.

6
Ben Voigt

Quel mal avec ceci:

public abstract class MyClass {
    protected MyClass(int param)
    {
    }
}

Dans ce cas, vous obligez toutes les classes dérivées à appeler le constructeur de la classe de base.

4
Sergey Teplyakov

Parce que les constructeurs abstraits ne sont pas supportés.

Mais une classe abstraite peut avoir un constructeur.

3
Davy Landman

Un constructeur n'est pas une méthode ordinaire. Il a un objectif particulier et est donc limité aux fonctionnalités linguistiques qui ont du sens à cet effet. Voir aussi: Pourquoi les constructeurs ne renvoient-ils pas de valeurs?

1
Daniel Earwicker

Par définition, la classe ne peut pas être instanciée directement, donc, dans un sens, elle est déjà abstraite.

0
Michael Bray