Constructor de una clase abstracta en C #

¿Por qué es posible escribir constructor para una clase abstracta en C #?
Por lo que yo sé, no podemos instanciar una clase abstracta … ¿para qué sirve?
No puedes instanciar la clase, ¿verdad?

Porque puede haber una forma estándar de instanciar los datos en la clase abstracta. De esta forma, puede hacer que las clases heredadas de esa clase llamen al constructor base.

public abstract class A{ private string data; protected A(string myString){ data = myString; } } public class B : A { B(string myString) : base(myString){} } 

Hasta donde yo sé, no podemos instanciar una clase abstracta

Ahí está tu error ahí mismo. Por supuesto, puedes instanciar una clase abstracta.

 abstract class Animal {} class Giraffe : Animal {} ... Animal animal = new Giraffe(); 

Hay una instancia de Animal allí mismo. Crea una instancia de una clase abstracta haciendo una clase concreta derivada de ella y creando una instancia de eso. Recuerde, una instancia de una clase concreta derivada también es una instancia de su clase base abstracta. Una instancia de Jirafa es también una instancia de Animal, incluso si Animal es abstracto.

Dado que puede instanciar una clase abstracta, necesita tener un constructor como cualquier otra clase, para asegurarse de que se cumplan sus invariantes.

Ahora, una clase estática es una clase que realmente no puede crear instancias, y notará que no es legal crear un constructor de instancias en una clase estática.

Es una forma de aplicar un conjunto de invariantes de la clase abstracta. Es decir, no importa lo que haga la subclase, quiere asegurarse de que algunas cosas siempre sean ciertas para la clase base … ejemplo:

 abstract class Foo { public DateTime TimeCreated {get; private set;} protected Foo() { this.TimeCreated = DateTime.Now; } } abstract class Bar : Foo { public Bar() : base() //Bar's constructor's must call Foo's parameterless constructor. { } } 

No piense en un constructor como el doble del new operador. El único propósito del constructor es asegurarse de tener un objeto en un estado válido antes de comenzar a usarlo. Simplemente sucede que normalmente lo llamamos a través de un new operador.

Está ahí para aplicar alguna lógica de inicialización requerida por todas las implementaciones de su clase abstracta, o cualquier método que haya implementado en su clase abstracta (no todos los métodos en su clase abstracta tienen que ser abstractos, algunos pueden implementarse).

Cualquier clase que herede de su clase base abstracta estará obligada a llamar al constructor base.

Normalmente los constructores implican inicializar los miembros de un objeto que se está creando. En el concepto de herencia, típicamente cada constructor de clase en la jerarquía de herencia, es responsable de crear instancias de sus propias variables miembro. Esto tiene sentido porque la creación de instancias tiene que hacerse donde las variables están definidas.

Como una clase abstracta no es completamente abstracta (a diferencia de las interfaces), es una mezcla de miembros abstractos y concretos, y los miembros que no son abstractos son necesarios para inicializarse, lo que se hace en constructores de clases abstractas, es necesario tener constructores en la clase abstracta Por supuesto, los constructores de la clase abstracta solo pueden invocarse desde los constructores de la clase derivada.

Puede crear una instancia después de implementar todos los métodos. Entonces se llamará al constructor.

Yo también quiero hacer un poco de brillo en la superficie abstracta. Todas las respuestas han cubierto casi todas las cosas. Todavía mis 2 centavos

las clases abstractas son clases normales con algunas excepciones

  1. Cualquier cliente / consumidor de esa clase no puede crear un objeto de esa clase, nunca significa que su constructor nunca lo llame. Su clase derivada puede elegir a qué constructor llamar (como se muestra en alguna respuesta)
  2. Puede tener una función abstracta.

Definición de un constructor con clase de almacenamiento pública o interna en una clase concreta heredable. Thing define efectivamente dos métodos:

  • Un método (que llamaré InitializeThing ) que actúa sobre this , no tiene valor de retorno, y solo se puede CreateThing métodos CreateThing e InitializeThing de Thing y los métodos InitializeThing subclases.

  • Un método (que llamaré CreateThing ) que devuelve un objeto del tipo designado por el constructor, y esencialmente se comporta como:

     Thing CreateThing(int whatever) { Thing result = AllocateObject(); Thing.initializeThing(whatever); } 

Las clases abstractas crean efectivamente métodos de solo la primera forma. Conceptualmente, no hay ninguna razón por la que los dos “métodos” descritos anteriormente deberían tener los mismos especificadores de acceso; en la práctica, sin embargo, no hay forma de especificar su accesibilidad de manera diferente. Tenga en cuenta que, en términos de implementación real, al menos en .NET, CreateThing realidad no se implementa como un método invocable, sino que representa una secuencia de código que se inserta en un newThing = new Thing(23); statement.

una clase abstracta puede tener variables miembro que se deben inicializar, por lo que se pueden inicializar en el constructor de la clase abstracta y se llama a este constructor cuando se inicializa el objeto de clase derivado.

Hay dos siguientes características importantes que evitan heredar la clase Abstract

  1. La clase abstracta debe tener un método abstracto; de lo contrario, no es una clase abstracta

  2. La clase abstracta debe ser heredada por la clase derivada, entonces si una clase es heredada por otra clase de la que se usa para crear un objeto de esa clase

Desde https://msdn.microsoft.com/en-us/library/ms182126.aspx

Los constructores en tipos abstractos solo pueden llamarse por tipos derivados. Debido a que los constructores públicos crean instancias de un tipo y no puede crear instancias de un tipo abstracto, un tipo abstracto que tiene un constructor público está incorrectamente diseñado.

Como solo las clases derivadas pueden usar un constructor de clase abstracto, un constructor de clase abstracto, si es necesario, debe declararse como protected .

Sin embargo, dicho comstackdor VS no se quejará (con reglas predeterminadas) al declarar constructores públicos en clases abstractas, sin embargo, no permitirá la creación de una nueva instancia.