Constructeur abstrait en C #

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

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

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

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’entre eux, même si vous appelez automatiquement celui par défaut), mais pas en dérivant en dérivant des classes. 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. Vous ne pouvez pas 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 à 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 ssortingng Name { get; private set; } protected Foo( ssortingng name ) { this.Name = name; } } public class Bar : Foo { public Bar() : base("bar") { ... } } 

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

Abstract implique virtuel. Un constructeur autre que le constructeur par défaut ne peut jamais être appelé de manière polymorphe, de sorte que les constructeurs ne sont pas autorisés à utiliser les constructeurs virtuels et abstraits.

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

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 remplacées . C’est-à-dire qu’ils ne sont pas hérités mais peuvent être redéfinis.

 public BaseClass { public BaseClass( Ssortingng s ) { ... } public static void doIt ( Ssortingng s ) { ... } } public SubClass extends BaseClass { public SubClass( Ssortingng s ) { ... } public static void doIt ( Ssortingng 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 ne sont jamais dissortingbués dynamicment (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 un constructeur abstrait et une méthode statique abstraite . C’est pourquoi vous ne pouvez pas non plus spécifier de constructeur et de méthode statique dans les interfaces .

Vous pouvez même considérer le constructeur comme une méthode de fabrique statique (et voir le modèle correspondant ):

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

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

Remarque : dans les langages tels que Smalltalk où les classes sont des objects réguliers, 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 objects “réguliers” même si vous pouvez les obtenir avec la reflection.

Quel est le problème 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.

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

Mais une classe abstraite peut avoir un constructeur.

Un constructeur n’est pas une méthode ordinaire. Il a un but particulier et se limite donc aux fonctionnalités linguistiques qui ont un sens à cette fin. Voir aussi: Pourquoi les constructeurs ne renvoient-ils pas de valeurs?

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