Costruttore astratto in C #

Possibile duplicato:
Perché non posso creare un costruttore astratto su una class C # astratta?

Perché non posso dichiarare astratto un costruttore della mia class in questo modo:

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

I costruttori sono applicabili solo alla class in cui sono definiti, cioè non sono ereditati. I costruttori di class base vengono utilizzati (è necessario chiamare uno di essi, anche se solo chiamando automaticamente quello predefinito) ma non sovrascritto derivando le classi. È ansible definire un costruttore su una class base astratta: non può essere utilizzato direttamente, ma può essere richiamato dalle classi derivate. Ciò che non si può fare è forzare una class derivata ad implementare una specifica firma del costruttore.

È perfettamente ragionevole definire un costruttore, tipicamente come protetto, al fine di definire un codice di impostazione comune per tutte le classi derivate. Ciò è particolarmente vero, forse, quando la class astratta fornisce un altro comportamento predefinito che si basa su questa configurazione. Per esempio:

 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") { ... } } 

Non puoi dichiararlo abstract , ma puoi avere un costruttore nella tua class astratta; basta rimuovere la parola abstract e fornire un corpo per questo.

L’astratto implica virtuale. Un costruttore non predefinito non può mai essere chiamato polimorficamente, quindi i costruttori non sono consentiti né virtuali né astratti.

Se in una versione futura di C #, i generici sono migliorati per consentire il richiamo di costruttori non predefiniti attraverso un parametro di tipo generico, sarebbero quindi possibili chiamate polimorfiche ai costruttori e potrebbero essere aggiunti anche costruttori virtuali e astratti.

I costruttori sono più vicini ai metodi statici piuttosto che ai metodi “regolari”. Come i metodi statici, possono essere sovraccaricati , ma non sostituiti . Cioè, non sono ereditati ma possono essere ridefiniti.

 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 

Costruttori e metodi statici non vengono mai inviati dynamicmente (virtualmente): si conosce sempre il tipo concreto istanziato o la class concreta del metodo statico. Ecco perché non ha senso avere un costruttore astratto e un metodo statico astratto . Ecco perché non è ansible specificare il metodo di costruzione e statico nelle interfacce .

Si può anche pensare al costruttore come metodo statico di fabbrica (e vedere il modello corrispondente ):

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

L’unico caso che vedo dove avrebbe senso definire il costruttore astratto o il metodo statico astratto sarebbe se si usasse la riflessione . In questo caso, è ansible assicurarsi che tutta la sottoclass ridisegni il metodo o il costruttore statico corrispondente. Ma la riflessione è un altro argomento …

Nota : in linguaggi come Smalltalk in cui le classi sono oggetti regolari, è ansible sovrascrivere il metodo statico e disporre di un costruttore astratto. Ma non si applica a Java perché le classi non sono oggetti “regolari” anche se è ansible ottenerle con la riflessione.

Cosa c’è di sbagliato in questo:

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

In questo caso, obbliga tutte le classi derivate a chiamare il costruttore della class base.

Perché i costruttori astratti non sono supportati.

Ma una class astratta può avere un costruttore.

Un costruttore non è un metodo ordinario. Ha uno scopo speciale e quindi è limitato alle funzionalità linguistiche che hanno senso per questo scopo. Vedi anche: Perché i costruttori non restituiscono valori?

Per definizione, la class non può essere istanziata direttamente, quindi in un certo senso è già astratta.