Recortes de mi Webeo


Herencia en C#

Posted in Net por novaxo en 27 junio, 2007

Concepto de herencia

El concepto de herencia tiende a confundir a muchos programadores ya que pretenden entenderlo desde el punto de vista del significado de la misma palabra, cuando la herencia en programación se refiere a la “clasificación”; es una relación entre clases, además es importante tener claro que la herencia es una relación de clases más que una relación de objetos.

Un ejemplo del concepto de herencia es por ejemplo que un empleado es una persona. Entonces podemos hacer un modelo de ello en .NET creando dos clases, una llamada Empleado y otra llamada Persona, y declarar que Empleado hereda de Persona. La herencia nos dice que hay una relación y establece el hecho de que todos los empleados son personas.

        class ClaseDerivada : ClaseBase
        {
            ...
        }

Clases base y clases derivadas

La sintaxis para declarar que una clase hereda de otra es:

La clase System.Object es la clase raíz para todas las clases, eso quiere decir que cuando declaramos una clase que no deriva explícitamente de otra, entonces el compilador define como clase base a System.Object.

Una clase puede tener como mucho una sola clase base. La clase derivada puede entonces llamar desde su constructor al constructor de su clase base.

        class  Empleado : Persona
        {
            public Empleado(string nombre) : base(nombre)    // base(nombre) llama a Persona(nombre)
            {
                ...
            }
            ...
        }

El método new (palabra clave new)

Aunque lo recomendable sería no tener métodos con la misma signatura (el nombre del método y número y tipo de sus parámetros) entre una clase derivada y su clase base, se puede lograr evitar el aviso del compilador que indica que hay ocultación de métodos utilizando la palabra clave new. Se debe considerar que los métodos aunque tengan el mismo nombre no guardan ninguna relación entre si, aun usando new.

Por ejemplo si tenemos un método con el mismo nombre en nuestra clase base Persona y la clase derivada Empleado llamado Nombre, entonces para evitar el ocultamiento del método deberá usarse la palabra clave new como sigue:

        class Persona
        {
            ...
            public string Nombre() {...}
        }

        class  Empleado : Persona
        {
            ...
            new public string Nombre() {...}
        }

Como hemos mencionado anteriormente el uso de new no evita el ocultamiento, únicamente evita el aviso del compilador. Siguiendo el ejemplo anterior cualquier llamada al método Nombre() aun desde una instancia de la clase Empleado se ejecutará el código del método Nombre() de la clase Persona ya que los dos métodos no guardan ninguna relación y se ocultan efectivamente uno del otro.

Métodos virtuales (palabra clave virtual)

Siguiendo con el ejemplo que venimos manejando digamos que realmente lo que queremos es implementar el mismo método más de una vez. Para ello recurrimos al poliformismo que significa literalmente “muchas formas”, logrando conectar los métodos Nombre() de las clases base y derivada y declarar que son dos implementaciones del mismo método. Hay que usar explícitamente la palabra clave virtual para activar el poliformismo para un método dado. Así:

        class Persona
        {
            ...
            public virtual string Nombre() {...}
        }

De esa manera se indica que es la primera implementación del método Nombre(). En C# un métodos no es virtual por defecto.

Métodos de reemplazo (palabra clave override)

Luego que hemos declarado un método como virtual en la clase base, entonces podemos usar la palabra clave override en la clase derivada para declarar otra implementación de ese método.

        class  Empleado : Persona
        {
            ...
            public override string Nombre() {...}
        }

Utilizando esta combinación de declaraciones (virtual y override) logramos entonces que el compilador llame a la implementación “más derivada” de Persona.Nombre() que para el siguiente ejemplo sería la de la instancia de Empleado.

Métodos de acceso protegido (palabra clave protected)

La pablara clave protected nos permite definir una relación de la clase derivada a la clase base, todo eso gracias a la conexión de las clases definida por la herencia. En términos generales lo que nos permite protected es acceder a un miembro protegido de una clase base desde una clase derivada de esta. Es decir que un miembro protegido de una clase base es en realidad público para la clase derivada. Por lo contrario una clase que no es derivada no puede acceder a un miembro protegido de una clase o dicho en otras palabras, dentro de una clase que no es una clase derivada, un miembro protegido de una clase es en realidad privado.

Interfaces

Utilizar la herencia de clases en nuestros proyectos de desarrollo es de por sí una práctica importante y son muy tangibles los beneficios que como desarrolladores logramos, pero la verdadera razón de que exista la herencia son las interfaces. Una interfaz permite separar completamente el nombre de un método de la implementación de ese método. La interfaz solamente dice cuál es el nombre del método, como se implementa exactamente el método no es asunto de la interfaz.

Una interfaz especifica un contrato sintáctico y semántico al cual se deben adherir todas las clases derivadas. Específicamente, una interfaz describe la parte del qué del contrato, y las clases que implementan la interfaz describen la parte del cómo del mismo.

Vamos a declarar entonces una interfaz que defina que toda clase que implemente dicha interfaz debe tener un método Nombre().

        interface IPersona
        {
            // Define el "que"
            string Nombre();
        }

Ahora implementemos esta interfaz declarando una clase que herede de la interfaz y que implemente para este caso el método Nombre().

        class Persona : IPersona
        {
            ...

            public string Nombre()
            {
                // Define el "como"
                ...
            }
        }

Finalmente como hemos visto antes si es necesario reemplazar la implementación de un método de una clase en otra clase derivada de ella, se debe declarar que ese método de clase es virtual. Nuestro ejemplo quedaría así:

        interface IPersona
        {
            // Define el "que"
            string Nombre();
        }

        class Persona : IPersona
        {
            ...

            public virtual string Nombre()
            {
                // Define el "como" para la clase base Persona.
                ...
            }
        }

        class Empleado : Persona
        {
            ...

            public override string Nombre()
            {
                // Define el "como" para la clase derivada Empleado.
                ...
            }
        }

Fuente del recorte

Anuncios

4 comentarios to 'Herencia en C#'

Subscribe to comments with RSS o TrackBack to 'Herencia en C#'.

  1. frank said,

    Hola, muchas gracias por el artículo, está muy claro todo y bien explicado.

  2. jdm said,

    no entiendo mucho como aplicar una clase… ;(

  3. gregro said,

    intenta con algo mas complej o y compreto por que tus comentarios todos tenemos estilos de programar y los comentariios muchas veces confunden mas de la estructura intenta hacerlo completo y con comentarios que definan mas cada parte del codigo porfavor

  4. mak said,

    Esta muy bueno.


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s


A %d blogueros les gusta esto: