method - Constructor de una clase abstracta en C#
polimorfismo c# (11)
¿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?
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.
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
- 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)
- 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 sobrethis
, no tiene valor de retorno, y solo se puedeCreateThing
métodosCreateThing
eInitializeThing
deThing
y los métodosInitializeThing
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>(); 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);
declaración.
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 compilador 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.
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.
Hay dos siguientes características importantes que evitan heredar la clase Abstract
La clase abstracta debe tener un método abstracto; de lo contrario, no es una clase abstracta
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
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.
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){}
}
Puede crear una instancia después de implementar todos los métodos. Entonces se llamará al constructor.
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.