Introducción: ¿por qué el constructor de la clase base no es solo "teoría aburrida"?
\n\nImagine que está construyendo una casa. Tiene una base (clase base) y la casa en sí (clase derivada). La base ya está puesta, pero para que la casa se mantenga firme, debe "conectarla" correctamente con la base. En C#, esta "conexión" se realiza mediante la llamada al constructor de la clase base a través de la palabra clave base.
Este es uno de esos temas que generan miles de preguntas en Stack Overflow. ¿Por qué? Porque sin entender este mecanismo, su código no se compilará o funcionará de manera impredecible. En este artículo, analizaremos la llamada al constructor de la clase base en C# de lo simple a lo complejo: con ejemplos, dificultades y escenarios reales.
\n\n¿Qué aprenderá en este artículo?
\n- \n
- Cómo funciona la herencia de constructores en C#. \n
- Cuándo y por qué es necesario llamar explícitamente a
base(). \n - Cómo pasar parámetros al constructor de la clase base. \n
- Errores típicos y cómo evitarlos. \n
- Técnicas avanzadas: cadenas de constructores y sobrecarga. \n
1. Conceptos básicos: ¿qué es un constructor de clase base?
\n\nEn C#, cada clase puede tener uno o más constructores. Cuando crea una instancia de una clase derivada, lo primero que se llama es el constructor de la clase base. Esto garantiza que todos los campos y propiedades del "padre" se inicialicen antes de que el "hijo" comience a funcionar.
\n\nSi no especifica explícitamente qué constructor de la clase base llamar, el compilador intentará llamar al constructor predeterminado (sin parámetros). Si no existe, obtendrá un error de compilación.
\n\nEjemplo 1: llamada implícita (todo simple)
\npublic class Animal\n{\n public string Name { get; set; }\n\n public Animal()\n {\n Name = "Animal desconocido";\n Console.WriteLine("Animal: constructor sin parámetros");\n }\n}\n\npublic class Dog : Animal\n{\n public Dog()\n {\n Console.WriteLine("Dog: constructor");\n }\n}\n\n// Uso\nDog dog = new Dog();\n// Salida:\n// Animal: constructor sin parámetros\n// Dog: constructor\n\nAquí, Dog llama implícitamente a Animal(). Todo funciona porque Animal tiene un constructor predeterminado.
2. El problema: cuando no hay constructor predeterminado
\n\nAhora imagine que la clase base requiere parámetros obligatorios. Por ejemplo, un animal debe tener un nombre. Si elimina el constructor sin parámetros, el código dejará de compilarse.
\n\nEjemplo 2: error de compilación
\npublic class Animal\n{\n public string Name { get; }\n\n public Animal(string name) // único constructor\n {\n Name = name;\n }\n}\n\npublic class Dog : Animal\n{\n // Error CS7036: "Animal" no contiene un constructor que tome 0 argumentos\n public Dog() \n {\n }\n}\n\nEl compilador grita: "¡Oye, no sé cómo inicializar Animal sin un nombre!". La solución es llamar explícitamente al constructor de la clase base con base.
3. La palabra clave base: llamada explícita al constructor
\n\nLa palabra clave base en C# se utiliza para acceder a los miembros de la clase base. En el contexto de los constructores, permite especificar qué constructor del padre se debe llamar y con qué argumentos.
Sintaxis:
\npublic class ClaseDerivada : ClaseBase\n{\n public ClaseDerivada(parámetros) : base(argumentos)\n {\n // cuerpo del constructor\n }\n}\n\nLos dos puntos y base(argumentos) se colocan inmediatamente después de la firma del constructor, antes del cuerpo.
Ejemplo 3: corregimos el error
\npublic class Animal\n{\n public string Name { get; }\n\n public Animal(string name)\n {\n Name = name;\n Console.WriteLine($"Animal: creado {name}");\n