Herencia en C#

Herencia en C#

Herencia en C# con ejemplos

En este artículo, voy a hablar sobre la herencia en la programación orientada a objetos usando C# Lenguaje con ejemplos. La herencia es uno de los principios de la programación orientada a objetos. Lea nuestra clase y objeto en C# artículo antes de pasar a este artículo. Entonces, entendamos qué es esta herencia.

¿Qué es la herencia en C#?

La herencia en C# es un mecanismo para consumir los miembros definidos en una clase de otra clase. Mira, somos conscientes de que una clase es una colección de miembros. Y los miembros definidos en una clase se pueden consumir de otra clase estableciendo una relación padre/hijo entre las clases.

Por lo general, todos sabemos una cosa:todas nuestras propiedades principales nos pertenecen. Entonces, los niños obtienen derechos sobre la propiedad de los padres. Por qué, porque esto es una ley. De acuerdo con la ley, todas las propiedades de los padres pertenecen a sus hijos.

Exactamente el mismo principio se aplica en la herencia. Supongamos que tengo una clase (A) con un conjunto de miembros y quiero los mismos miembros en otra clase (B). Una forma de hacer esto es, necesito copiar y pegar el mismo código de la clase A en la clase B. Pero si copiamos y pegamos el código, entonces se llama reescribir el código. Reescribir el código tiene un impacto en el tamaño de la aplicación. Si el tamaño de la aplicación crece, finalmente afectará el rendimiento de la aplicación.

Entonces, si desea superar ese proceso de reescritura y reutilizar el código, la mejor opción disponible para nosotros es Herencia en C#. Simplemente. lo que tenemos que hacer es establecer una relación entre las dos clases. ¿Qué relación? Relación padre/hijo. Una vez que haya establecido la relación principal/secundario, todos los miembros de la clase principal (A) se pueden consumir en la clase secundaria (B). Para una mejor comprensión, observe el siguiente diagrama.

Por lo tanto, la herencia en C# es un mecanismo para consumir los miembros de una clase en otra clase al establecer una relación principal/secundario entre las clases que brinda reutilización.

¿Cómo implementar la herencia en C#?

Para implementar la herencia en C#, necesitamos establecer una relación padre/hijo entre las clases. Comprendamos cómo establecer una relación padre/hijo en C#. Supongamos que tenemos una clase llamada A con un conjunto de miembros. Y tenemos otra clase B y queremos que esta clase B se herede de la clase A. El siguiente código muestra cómo establecer la relación padre-hijo entre la clase A y la clase B.

Entonces, este es el proceso básico para establecer una relación padre/hijo en C#. Ahora, veamos la sintaxis básica para establecer una relación padre/hijo entre clases. La sintaxis se proporciona a continuación.

[] clase :

Aquí, la terminología clase principal y clase secundaria también se puede denominar clase base (superclase) y clase derivada (subclase). Entonces, en nuestro ejemplo,
A => Padre/ Base/ Superclase (todos significan lo mismo; puede usar cualquier término)
B => Hijo/ Derivado/ Subclase (todos significan lo mismo; puede usar cualquier término)

Nota: En herencia, la clase secundaria puede consumir miembros de su clase principal como si fuera el propietario de esos miembros (espere los miembros privados de la principal).

¿Por qué el niño no puede consumir miembros privados de los padres?

Por lo general, los hijos tienen derechos sobre la propiedad de sus padres. Como un niño, mañana puedo hacerme cargo del negocio de mi padre. Puedo tomar posesión de las Propiedades de mi Padre (Automóvil, Edificios, Dinero, lo que sea). Pero no puedo hacerme cargo del trabajo de mi padre. La razón es que el Trabajo, sea lo que sea que esté haciendo mi padre, puede estar basado en sus calificaciones y sus experiencias. Y mañana no puedo hacerme cargo de su trabajo particular. Entonces, el trabajo es completamente privado para mi padre. Y eso no se me hereda. Pero quede todo, negocios, dinero, propiedades, todo lo que tomaré. Toma el control de todo excepto de los miembros privados.

El mismo principio también se aplica a la Herencia. Entonces, la clase secundaria consumirá todos los miembros de la clase principal excepto los miembros privados.

Ejemplo para comprender la herencia en C#:

Veamos un ejemplo simple para entender la herencia en C#. Vamos a crear una clase, con dos métodos como se muestra a continuación.

class A
{
    public void Method1()
    {
        Console.WriteLine("Method 1");
    }
    public void Method2()
    {
        Console.WriteLine("Method 2");
    }
}

Aquí, hemos creado la clase A con dos métodos públicos, es decir, Method1 y Method2. Ahora, quiero los mismos dos métodos en otra clase, es decir, la clase B. Una forma de hacerlo es copiar los dos métodos anteriores y pegarlos en la clase B de la siguiente manera.

class B
{
    public void Method1()
    {
        Console.WriteLine("Method 1");
    }
    public void Method2()
    {
        Console.WriteLine("Method 2");
    }
}

Si hacemos esto, entonces no es reutilización de código. Es la reescritura de código lo que afecta el tamaño de la aplicación. Entonces, sin reescribir, lo que debemos hacer es realizar la herencia aquí de la siguiente manera. Aquí, la clase B se hereda de la clase A y, por lo tanto, dentro del método principal, creamos una instancia de la clase B e invocamos los métodos que se definen en la clase A.

class B : A
{
    static void Main()
    {
        B obj = new B();
        obj.Method1();
        obj.Method2();
    }
}

Una vez que realiza la Herencia, la clase B puede tomar los dos miembros definidos en la clase A. ¿Por qué? Porque todas las propiedades de un Padre pertenecen a los Hijos. Aquí, la clase A es la clase principal/superior/base y la clase B es la clase secundaria/secundaria/derivada.

Entendamos una cosa más. Por favor observe la siguiente imagen. Cuando decimos obj. puede ver la inteligencia que muestra los dos métodos, es decir, Method1 y Method2. Por lo tanto, la clase secundaria puede consumir los miembros de la clase principal como si fuera el propietario. Ahora, si ve la descripción de Method1 o Method2, muestra void A.Method1() y void A.Method2(). Eso significa que Method1 o Method2 pertenecen solo a la clase A. Pero la clase B puede consumir al miembro como si fuera el propietario. Mira, puedo conducir el auto de mi padre como si fuera el dueño, pero aún así, el nombre de registro es mi padre. De manera similar, la clase B puede llamar a los métodos ya que el método es propio pero internamente los métodos pertenecen a la Clase A.

El código de ejemplo completo se muestra a continuación. En el siguiente ejemplo, la clase A definió dos miembros y la clase B se hereda de la clase A. En la clase B, dentro del método principal, creamos una instancia de la clase B y llamamos a los dos métodos.

using System;
namespace InheritanceDemo
{
    class A
    {
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        static void Main()
        {
            B obj = new B();
            obj.Method1();
            obj.Method2();
            Console.ReadKey();
        }
    }
}
Salida:

Ahora, agreguemos un nuevo método, es decir, Method3 en la Clase B de la siguiente manera. Y dentro del método Main, si ve la descripción del método, muestra que el método pertenece a la clase B.

El ejemplo completo se muestra a continuación.

using System;
namespace InheritanceDemo
{
    class A
    {
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            B obj = new B();
            obj.Method1();
            obj.Method2();
            obj.Method3();
            Console.ReadKey();
        }
    }
}
Salida:

¿Cuántos métodos hay en la clase B?

Ahora, puede que tenga una pregunta, ¿cuántos métodos hay en la clase B? La respuesta es 3. Vea que todas las propiedades que mi padre me ha dado más todas las propiedades que estoy ganando son solo de mi propiedad. Entonces, ¿cuál es mi propiedad? No digo lo que gané, también digo lo que mi padre me ha dado. Entonces, de la misma manera, cuántos métodos hay en la clase B significa 3 métodos. Se heredaron dos métodos de la clase principal A más un método que definimos en la clase B. Entonces, podemos decir que la clase A contiene dos métodos y la clase B contiene 3 métodos.

Este es el proceso simple de Herencia en C#. Simplemente coloque dos puntos (:) entre la clase Padre e Hijo. Pero cuando se trabaja con Herencia 6, se requieren cosas o reglas para aprender y recordar. Aprendamos esas 6 Reglas importantes una por una.

Regla 1:

En C#, el constructor de las clases principales debe ser accesible para la clase secundaria, de lo contrario, la herencia no sería posible porque cuando creamos el objeto de la clase secundaria primero, va y llama al constructor de la clase principal para que la variable de la clase principal se inicialice y podamos consumirla en la clase secundaria.

En este momento, en nuestro ejemplo, tanto la clase A como la clase B tienen constructores implícitos. Sí, cada clase en C# contiene un constructor implícito si como desarrollador no definimos ningún constructor explícitamente. Ya lo aprendimos en nuestra sección de constructores.

Si un constructor se define implícitamente, entonces es un constructor público. En nuestro ejemplo, la clase B puede acceder implícitamente al constructor de la clase A, ya que es público. Ahora, definamos un constructor explícito en la Clase A de la siguiente manera.

class A
{
    public A()
    {
        Console.WriteLine("Class A Constructor is Called");
    }
    public void Method1()
    {
        Console.WriteLine("Method 1");
    }
    public void Method2()
    {
        Console.WriteLine("Method 2");
    }
}

Con los cambios anteriores implementados, si ejecuta el código de la aplicación, obtendrá el siguiente resultado.

Cuando ejecuta el código, primero se llama al constructor de clase A y eso es lo que puede ver en la salida. ¿Por qué? Esto se debe a que, cada vez que se crea la instancia de la clase secundaria, el constructor de la clase secundaria llamará implícitamente a los constructores de la clase principal. Esta es una regla.

En este momento, la clase secundaria contiene un constructor implícito, y ese constructor implícito llama al constructor de la clase principal. Pero el constructor de la clase principal A no está implícitamente, está explícitamente ahora y dentro de ese constructor de la clase principal, hemos escrito una declaración de impresión y una declaración de impresión que imprime algún mensaje en la ventana de la consola.

Pero recuerde, si está definiendo un constructor explícito, si hace que ese constructor sea privado y no proporciona un especificador de acceso, entonces, por defecto, el especificador de acceso del miembro de la clase es privado. Cía#. Por ejemplo, modifique la clase A de la siguiente manera. Como puede ver, hemos eliminado el especificador de acceso del constructor, lo que lo hace privado.

class A
{
    A()
    {
        Console.WriteLine("Class A Constructor is Called");
    }
    public void Method1()
    {
        Console.WriteLine("Method 1");
    }
    public void Method2()
    {
        Console.WriteLine("Method 2");
    }
}

Como puede ver en el código, el constructor Clase A es privado, por lo que no es accesible para la clase B. Ahora, si intenta ejecutar el código, obtendrá el siguiente error de tiempo de compilación como se muestra en la imagen de abajo que le dice a Class Un Constructor es inaccesible debido a su nivel de protección .

Obtenemos el error anterior porque, cuando creamos una instancia de la clase secundaria, el constructor de la clase secundaria llamará implícitamente a los constructores de la clase principal. En este momento, el constructor de la clase B intenta llamar al constructor de la Clase A al que no se puede acceder porque ese constructor es privado.

Hagamos una cosa más. Definamos un constructor en la Clase B también de la siguiente manera. Hagamos público el constructor de clase A, de lo contrario, la herencia no sería posible.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A()
        {
            Console.WriteLine("Class A Constructor is Called");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            B obj = new B();
            obj.Method1();
            obj.Method2();
            obj.Method3();
            Console.ReadKey();
        }
    }
}
Salida:

Como puede ver en el resultado anterior, primero se llama al constructor de clase A y luego se llama al constructor de clase B. Entonces, el punto que debe recordar es que la ejecución siempre comienza desde el constructor de la clase principal. ¿Por qué? Porque cuando creamos una instancia de una clase secundaria, el constructor de la clase secundaria llamará implícitamente al constructor de la clase principal. Si esa clase principal tiene una clase principal, entonces ese constructor de clase principal llamará a su constructor de clase principal, y así sucesivamente. Suponga que tiene 5 clases en herencia, y si está creando una instancia de la 5 th clase, luego el 5 th constructor de clase llamará al 4 th constructor de clase y 4 th el constructor de la clase llamará al 3 rd constructor de clases y el 3 rd constructor de clase llamará al 2 nd constructor de clase y 2 do constructor de clase llamará al 1 st constructor de clases. Entonces, la ejecución, en este caso, comenzará desde el constructor de clase 1, luego el constructor de clase 2 y el último constructor, en este caso, será el 5 th constructor de clases.

¿Por qué el constructor de clase B no es público?

Aquí, puede tener una pregunta:el constructor de Clase B no es público. ¿Por qué? Mira, el constructor de la clase B no necesita ser público porque el constructor de la clase A debe ser accesible para B, no la clase B para la clase A. Cuando el constructor de la clase B debe ser público si la clase B tiene una clase secundaria, entonces el El constructor de clase B debe ser público. Si la clase B no tiene una clase secundaria, entonces no tiene sentido declarar el constructor como público. Si lo desea, también puede declarar el constructor como público. En este caso, eso no importa en absoluto.

Por lo tanto, siempre el constructor de la clase secundaria llama implícitamente al constructor de la clase principal y, por lo tanto, el constructor de la clase principal debe ser accesible para la clase secundaria; de lo contrario, la herencia no sería posible. Ahora, es posible que tenga una pregunta:¿por qué el constructor de la clase principal es accesible para la clase secundaria?

¿Por qué el constructor de la clase principal es accesible para la clase secundaria?

La razón es que cuando se llama al constructor de la clase principal, solo se inicializarán los miembros de la clase principal, y solo ellos podrán consumirse en la clase secundaria. Si los miembros de la clase principal no se inicializan, no puede consumirlos en la clase secundaria. Si desea consumirlos en la clase secundaria, deben inicializarse. Vea, la clase secundaria depende de la clase principal, por lo que la clase principal debe inicializarse primero, luego solo es posible el consumo en la clase secundaria.

Esta es la primera regla de la Herencia. Procedamos y comprendamos la segunda regla de Herencia en C# con ejemplos.

Regla 2:

En la herencia, la clase secundaria puede acceder a los miembros de la clase principal, pero las clases principales nunca pueden acceder a los miembros que están puramente definidos en la clase secundaria.

Mira, de acuerdo con la ley, los niños tienen derechos sobre la propiedad de sus padres. Pero el Padre no tiene derechos sobre la propiedad de los Hijos. Es responsabilidad de los niños cuidar de sus padres. Pero legalmente, el Padre no tiene derechos sobre la propiedad del niño. Exactamente de la misma manera, la clase principal nunca puede acceder a los miembros de la clase secundaria que están puramente definidos en la clase secundaria.

Entendamos esto con un ejemplo. Por favor, eche un vistazo al siguiente código. Aquí, puede ver dentro del método principal que estamos creando una instancia de la clase principal, es decir, A, y tratando de invocar la clase principal y los métodos de la clase secundaria. Cuando intentamos invocar el Método 3, que está puramente definido en la clase secundaria, obtendremos un error de tiempo de compilación.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A()
        {
            Console.WriteLine("Class A Constructor is Called");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            A obj = new A();
            obj.Method1();
            obj.Method2();
            //The following line of code gives you compile time error
            obj.Method3();
            Console.ReadKey();
        }
    }
}

Cuando intente ejecutar el código anterior, obtendrá el siguiente error de tiempo de compilación.

Se queja de que la clase 'A' no contiene una definición para 'Method3' y no hay un método de extensión accesible 'Method3' que acepte un primer argumento de tipo 'A' podría encontrarse (¿falta una directiva de uso o una referencia de ensamblado?) y esto tiene sentido.

Entonces, esta es la segunda regla de herencia que una clase principal nunca puede acceder a ningún miembro de la clase secundaria que esté puramente definido en la clase secundaria. En este caso, Method3 está puramente definido en la clase secundaria B y, por lo tanto, no podemos acceder a este método usando el objeto de la clase principal.

Regla 3:

Podemos inicializar una variable de clase principal utilizando la instancia de clase secundaria para convertirla en una variable de referencia, de modo que la referencia consuma la memoria de la instancia de clase secundaria. Pero en este caso, tampoco podemos llamar a ningún miembro de clase hijo puro usando la referencia.

Ahora, puede que tenga una pregunta, ¿qué es una referencia? La respuesta es una referencia que apunta a una instancia que no tiene ninguna asignación de memoria.

Entendamos esto con un ejemplo. Por favor, eche un vistazo al siguiente código. Dentro del método Main, primero, creamos una variable p de clase A y aquí p es una variable de referencia. No es una instancia, es una variable, es decir, una copia no inicializada

using System;
namespace InheritanceDemo
{
    class A
    {
        public A()
        {
            Console.WriteLine("Class A Constructor is Called");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            A p; //p is a variable of class A
            p.Method1();
            p.Method2();
            Console.ReadKey();
        }
    }
}

Ahora, si intenta ejecutar el código anterior, obtendrá el siguiente error de tiempo de compilación, es decir, Uso de variable local no asignada 'p' .

Esto tiene sentido. La variable p no está asignada y, por lo tanto, no podemos llamar a ningún método. No está inicializado. ¿Cómo inicializar una variable de referencia? La inicialización se puede realizar utilizando la nueva palabra clave en C#. Veamos esto. En el siguiente ejemplo, hemos inicializado la variable de referencia de la clase principal p usando la instancia de la clase secundaria y luego llamamos a los miembros de la clase principal. En el siguiente ejemplo, el código del método principal se explica por sí mismo, así que revise las líneas de comentarios.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A()
        {
            Console.WriteLine("Class A Constructor is Called");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            A p; //p is a variable of class A
            B q = new B(); //q is an instance of Class B 

            //We can initialize a Parent class variable using child class instance as follows
            p = q; //now, p is a reference of parent class created by using child class instance

            //Now you can call members of A class as follows
            p.Method1();
            p.Method2();

            //We cannot call any pure child class members using the reference p
            //p.Method3();
            Console.ReadKey();
        }
    }
} 
Salida:

Entonces, ¿qué es una referencia en C#?

Las referencias de una clase no tendrán ninguna asignación de memoria. Estarán consumiendo la memoria de la instancia que se asigne para inicializarlos. Para una mejor comprensión, por favor, eche un vistazo al siguiente diagrama. Aquí, cada vez que creamos una instancia, la memoria se asigna para q. Y esta instancia contendrá información sobre las clases Padre A y Niño B. Y p es una referencia. Y p está consumiendo la memoria de q.

Nota: El punto que debe recordar es que la asignación de memoria se realiza para instancias, no para referencias en C#. Las referencias son solo punteros a instancias.

Ahora, si observa que tanto p como q están accediendo a la misma memoria. Pero el punto a entender es que a pesar de que p y q están accediendo a la misma memoria, usando p, no puedo llamar a ningún miembro de clase hijo. Vea el siguiente diagrama. Como puede ver en el siguiente diagrama, usando p no podemos llamar a los miembros de la clase B, pero usando q podemos llamar a los miembros de la clase A y B.

Regla 4:

Cada clase definida por nosotros o predefinida en las bibliotecas del idioma tiene una clase principal predeterminada, es decir, la clase de objeto del espacio de nombres del sistema, por lo que los miembros (Equals, GetHashCode, GetType y ToString) de la clase Object son accesibles desde cualquier lugar.

Generalmente, cuando definimos una clase, pensamos que no la heredamos de ninguna clase. Pero por defecto, nuestra clase se hereda de la clase Object. Entonces, Object es la clase principal para todas las clases definidas en nuestra Biblioteca de clases base, así como para todas las clases que definimos en nuestra aplicación.

Debido a que Object es la clase principal, se puede llamar o acceder a cuatro métodos importantes (Equals, GetHashCode, GetType y ToString) de la clase Object desde cualquier lugar. Para una mejor comprensión, por favor, eche un vistazo a la imagen de abajo. Aquí, hemos creado una instancia de la clase Object y cuando decimos obj., la inteligencia muestra los cuatro métodos.

Recuerde que se puede acceder a los cuatro métodos anteriores desde cualquier lugar. Cada clase puede contener los métodos Equals, GetHashCode, GetType y ToString y esto es posible porque cada clase en el marco .NET se hereda de la clase Object.

Ahora, vamos a crear un objeto de clase A y cuando escribes obj., la inteligencia muestra 6 métodos, es decir, 2 métodos (Method1 y Method2) de la clase A y cuatro métodos (Equals, GetHashCode, GetType y ToString) de la clase Object que se muestra en la siguiente imagen.

Generalmente, cuando compilas tu código, el compilador verifica si esta clase hereda de cualquier otra clase. Si es así, no hay problemas. Si no, el compilador automáticamente hace que esta clase se herede de la clase Object. En nuestro ejemplo, la clase A no se hereda de ninguna clase. En el momento de la compilación, esta clase heredará automáticamente de la clase Object.

Por otro lado, al compilar la clase B, ¿verificará si la clase B se hereda de alguna otra clase? Sí, la clase B se hereda de la clase A. No, es necesario heredar de Object. La razón es que la clase A ya hereda de Object. Debido a que la clase A ya se hereda de Object, para la clase B también Object es la clase principal, tal vez sea un abuelo.

Entonces, el punto que debe recordar es que cada clase en .NET Framework se hereda directa o indirectamente de la clase Object.

Nota: La clase de objeto admite todas las clases en la jerarquía de clases de .NET Framework y proporciona servicios de bajo nivel a las clases derivadas. Esta es la última clase base de todas las clases en .NET Framework; es la raíz de la jerarquía de tipos.

¿Qué es la clase principal predeterminada en C#?

La clase principal predeterminada es la clase de objeto presente en el espacio de nombres del sistema.

Ahora, por favor, eche un vistazo al siguiente ejemplo. Aquí hemos creado tres instancias que son instancias de la clase Object, la clase A y la clase B y llamamos al método GetType. El método GetType devuelve el tipo de tiempo de ejecución exacto de la instancia actual. Le dirá el nombre completo, es decir, el espacio de nombres y el nombre de la clase.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A()
        {
            Console.WriteLine("Class A Constructor is Called");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            Object obj1 = new Object();
            Console.WriteLine($"obj1 type: {obj1.GetType()}");
            A obj2 = new A();
            Console.WriteLine($"obj2 type: {obj2.GetType()}");
            B obj3 = new B();
            Console.WriteLine($"obj3 type: {obj3.GetType()}");

            Console.ReadKey();
        }
    }
}
Salida:

Ejecución del constructor en el ejemplo anterior:
  1. Cuando creamos una instancia de la clase Object, solo se llama al constructor de la clase Object.
  2. Pero cuando creamos una instancia de Clase A, se llaman dos constructores. Primero, ejecutará el constructor de la clase Object y luego ejecutará el constructor de la Clase A.
  3. Cuando creamos una instancia de Clase B, se ejecutan tres constructores. Primero, ejecutará el constructor de la clase Object, luego ejecutará el constructor de la clase A y, por último, ejecutará el constructor de la clase B.
Regla 5:

En C# no tenemos soporte para herencias múltiples a través de clases, lo que se nos proporciona es solo herencia única a través de clases. Eso significa que con las clases, solo se permite una clase principal inmediata (es decir, única, multinivel y jerárquica) y no se permite más de una clase principal inmediata en C# con clases (es decir, no se admiten múltiples e híbridas). En nuestro próximo artículo, discutiremos esta regla en detalle.

Regla 6:

En la regla 1 aprendimos que cada vez que se crea la instancia de la clase secundaria, el constructor de la clase secundaria llamará implícitamente al constructor de la clase principal, pero si el constructor de la clase principal no tiene parámetros. Si el constructor de la clase Padre está parametrizado, entonces el constructor de la clase Hijo no puede llamar implícitamente al constructor de su Padre. Entonces, para superar este problema, es responsabilidad del programador llamar explícitamente al constructor de clases principales desde el constructor de clases secundarias y pasar valores a esos parámetros. Para llamar al constructor de Padres desde la clase secundaria, necesitamos usar la palabra clave base.

Entendamos esto con un ejemplo. Hagamos que el constructor de la clase Parent se parametrice de la siguiente manera. Aquí, el constructor toma un parámetro entero e imprime ese valor en la ventana de la consola.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A(int number)
        {
            Console.WriteLine($"Class A Constructor is Called : {number}");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }
    class B : A
    {
        public B()
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
      B obj = new B();
            Console.ReadKey();
        }
    }
}

Ahora, si compilas el código, verás que la clase B está dando un error como se muestra en la imagen de abajo.

Se queja de que "No se da ningún argumento que corresponda al parámetro formal requerido 'número' de 'A.A(int)'" y esto tiene sentido. Esto se debe a que el constructor de clase B llama implícitamente al constructor de clase A. Pero, si desea llamar al constructor de clase A, ahora requiere un parámetro entero. Sin pasar el parámetro no podemos llamar al constructor de clase A. Entonces, ahora el constructor de clase B no puede llamar al constructor de clase A.

¿Por qué no puede llamar al constructor?

Anteriormente, el constructor no tenía parámetros, por lo que llama directamente al constructor de la clase principal. En este momento, el constructor está parametrizado. Si desea llamarlo, necesita un valor ahora. Y el constructor de clase B no sabe qué valor pasar al constructor de clase A. Esta es la razón por la que recibimos un error en la clase B, no en la clase A. Porque la clase B no puede llamar al constructor de la clase A.

Entonces, ¿qué hacer? La llamada implícita no funciona. Entonces, para resolver el error, debemos realizar una llamada explícita. ¿Como llamar? Consulte el siguiente código. Aquí, la palabra clave base se refiere a la clase principal, es decir, la clase A. Y aquí debemos pasar el valor para la clase base o el constructor de la clase principal.

Entonces, aquí estamos pasando el valor 10 a la clase principal, es decir, un constructor. Y este valor 10 será recibido por el constructor de la clase padre. El código completo se proporciona a continuación.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A(int number)
        {
            Console.WriteLine($"Class A Constructor is Called : {number}");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }

    class B : A
    {
        public B() : base(10)
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            B obj = new B();
            Console.ReadKey();
        }
    }
}
Salida:

¿Cómo pasar el valor dinámico al constructor de la clase principal en C#?

En nuestro ejemplo anterior, hemos codificado el valor, es decir, 10. Por lo tanto, cada vez que creamos una instancia, se asignará el mismo valor al constructor principal. Pero si queremos, también podemos pasar el valor dinámico. Veamos esto con un ejemplo. En el siguiente ejemplo, la clase secundaria, es decir, el constructor de clase B, toma un parámetro y pasa ese valor de parámetro a la clase principal, es decir, el constructor de clase A. Y cuando estamos creando la instancia de Clase B, necesitamos pasar el valor del parámetro.

using System;
namespace InheritanceDemo
{
    class A
    {
        public A(int number)
        {
            Console.WriteLine($"Class A Constructor is Called : {number}");
        }
        public void Method1()
        {
            Console.WriteLine("Method 1");
        }
        public void Method2()
        {
            Console.WriteLine("Method 2");
        }
    }

    class B : A
    {
        public B(int num) : base(num)
        {
            Console.WriteLine("Class B Constructor is Called");
        }
        public void Method3()
        {
            Console.WriteLine("Method 3");
        }
        static void Main()
        {
            B obj1 = new B(10);
            B obj2 = new B(20);
            B obj3 = new B(30);
            Console.ReadKey();
        }
    }
}
Salida:

Entonces, en el ejemplo anterior, cuando estamos creando la instancia, estamos pasando el valor. El valor llega primero al constructor de la clase secundaria y el constructor de la clase secundaria pasa el mismo valor al constructor de la clase principal. Si lo desea, también puede usar el mismo valor en la clase secundaria.

Entonces, estas son las seis reglas que debe recordar mientras trabaja con Herencia en C#.

Ventajas de la herencia en C#:

Reutilización de código: Podemos reutilizar los miembros de la clase principal o la clase base en la clase secundaria o la clase derivada. Por lo tanto, no es necesario volver a definir los miembros en la clase secundaria. Por lo tanto, se requiere menos código en la clase.

En el próximo artículo, voy a hablar sobre Tipos de herencia en C# con ejemplos. Aquí, en este artículo, trato de explicar la herencia en C# con ejemplos y espero que disfrutes este artículo. Me gustaría tener sus comentarios. Publique sus comentarios, preguntas o comentarios sobre este artículo.