que - ¿Por qué no puedo crear un constructor abstracto en una clase abstracta de C#?
que es un constructor en c# (8)
Estoy creando una clase abstracta. Quiero que cada una de mis clases derivadas se vea obligada a implementar una firma específica de constructor. Como tal, hice lo que habría hecho si hubiera querido obligarlos a implementar un método, hice uno abstracto.
public abstract class A
{
abstract A(int a, int b);
}
Sin embargo, recibo un mensaje que dice que el modificador abstracto no es válido en este artículo. Mi objetivo era forzar un código como este.
public class B : A
{
public B(int a, int b) : base(a, b)
{
//Some other awesome code.
}
}
Este es todo el código C # .NET. ¿Puede alguien ayudarme?
Actualización 1
Yo quería agregar algunas cosas. Lo que terminé con esto fue esto.
private A() { }
protected A(int a, int b)
{
//Code
}
Eso hace lo que algunas personas dicen, el valor predeterminado es privado y la clase necesita implementar un constructor. Sin embargo, eso no FORCE un constructor con la firma A (int a, int b).
public abstract class A
{
protected abstract A(int a, int b)
{
}
}
Actualización 2
Debería ser claro, para evitar esto, hice mi constructor predeterminado privado, y mi otro constructor protegido. Realmente no estoy buscando una manera de hacer que mi código funcione. Me ocupé de eso. Estoy buscando entender por qué C # no te permite hacer esto.
Aunque no puede anular constructores, y por lo tanto no puede definir un constructor abstracto, puede colocar un método abstracto de fábrica en su clase base abstracta. Todas las clases derivadas necesitarían anular eso.
public abstract class A
{
abstract A MakeAInstance(int a, int b);
}
public class B : A
{
// Must implement:
override A MakeAInstance(int a, int b) {
// Awesome way to create a B instance goes here
}
}
Cambia ese constructor en la clase A a
protected A(int a, int b)
{
// Some initialisation code here
}
Entonces tus subclases tendrán que usarlo, ya que no hay un constructor predeterminado.
Sin embargo, aún pueden cambiar la firma real del constructor. No hay forma de forzar que una subclase use una firma específica para su constructor, hasta donde yo sé. Estoy bastante seguro de que los constructores no pueden ser abstractos.
¿Para qué necesitas esto exactamente? Es posible que podamos sugerir una solución para esto.
Espero que esto ayude a alguien nuevo como yo. Estaba buscando hacer una clase pública "normal" con un lector que toma argumentos y luego necesitaba convertirlo en una clase para niños, así que necesitaba una herramienta vacía para ello.
Yo no sabía esto antes: si haces un ctor protegido, la clase infantil lo ve pero el resto del programa no lo ve (supongo que mi confusión es porque en asp.net veo todo lo protegido en la página aspx que hereda de el cs ...)
Múltiples razones:
1) Los constructores no son heredados por lo que no puedes anularlos.
2) El constructor es una función miembro estática ya que no necesita una instancia específica para llamar. El resumen implica "virtual", lo que significa que la implementación puede variar según cómo se subclasifique una instancia específica, que es lo contrario de la intención del significado de la palabra clave "estática".
No puede tener un constructor abstracto porque abstracto significa que debe anularlo en cualquier clase secundaria no abstracta y no puede anular un constructor.
Si lo piensas bien, esto tiene sentido, ya que siempre llamas al constructor de la clase hija (con el nuevo operador) y nunca a la clase base.
En términos generales, la única forma en C # de imponer una firma de constructor específica es mediante el uso de la nueva () restricción genérica, que impone la existencia de un constructor sin parámetros para el parámetro de tipo.
No se puede forzar la firma del constructor, ya que cada clase derivada puede (¡debe!) Definir su propio constructor (es), y pueden tomar cualquier parámetro que deseen.
Si necesita pasar un conjunto dado de variables a un objeto de una clase derivada, defina un método abstracto que necesita implementarse por clases derivadas. Si las clases no implementan el método abstracto, obtendrá un error de compilación.
Todas las subclases siempre pueden especificar su propio constructor siempre que llamen a un constructor de la superclase, por lo que no hay forma de forzar a la clase a tener un constructor específico (al menos, así es como funciona en Java). Usted podría ver que usar un patrón de fábrica lo llevará a algún lugar, podría definir un método de fábrica en una interfaz, pero necesitará una clase de fábrica separada ya que su clase base abstracta no conoce la clase real del objeto que necesita ser creado.
Sin embargo: tal vez agregar un ejemplo más concreto del problema que está teniendo podría provocar otras / mejores respuestas. ¿Está buscando algún código genérico de creación de instancias, o le preocupa que se deba realizar una configuración específica en la clase base abstracta?
Si solo le preocupa la inicialización que tiene que hacer la clase abstracta, cree un método para hacerlo y documente el uso de ese método.
no estoy seguro de si esto ayuda, pero creo que esta sería una solución a su problema:
public class A
{
public A(int a, int b)
{
DoSomething(int a, int b);
}
virtual public void DoSomething(int a, int b)
{
}
}
public class B : A
{
override public void DoSomething(int a, int b)
{
//class specific stuff
}
}
con el resultado de que puede llamar a un constructor con los argumentos requeridos en cualquier clase derivada con el comportamiento correcto.