Herencia

5
Introducción Una de las propiedades más importantes de la Programación Orientada a Objetos es la abstracción de datos. Esta propiedad se manifiesta esencialmente en la encapsulación, que es la responsable de gestionar la complejidad de grandes programas al permitir la definición de nuevos tipos de datos: las clases. Sin embargo, la clase no es suficiente por sí sola para soportar diseño y programación orientada a objetos. Se necesita un medio para relacionar unas clases con otras. Un medio son las clases anidadas, pero sólo se resuelve parcialmente el problema, ya que las clases anidadas no tienen las características requeridas para relacionar totalmente una clase con otra. Se necesita un mecanismo para crear jerarquías de clases en las que la clase A sea afín a la clase B, pero con la posibilidad de poder añadirle también características propias. Este mecanismo es la herencia. La herencia es, seguramente, la característica más potente de la Programación Orientada a Objetos, después de las clases. Por herencia conocemos el proceso de crear nuevas clases, llamadas clases derivadas, a partir de una clase base. En C++ la herencia se manifiesta con la creación de un tipo definido por el usuario (clase), que puede heredar las características de otra clase ya existente o derivar las suyas a otra nueva clase. Cuando se hereda, las clases derivadas reciben las características (estructuras de datos y funciones) de la clase original, a las que se pueden añadir nuevas características o modificar las características heredadas. El compilador hace realmente una copia de la clase base en la nueva clase derivada y permite al programador añadir o modificar miembros sin alterar el código de la clase base. La derivación de clases consigue la reutilización efectiva del código de la clase base para sus necesidades. Si se tiene una clase base totalmente depurada, la herencia ayuda a reutilizar ese código en una nueva clase. No es necesario comprender el código fuente de la clase original, sino sólo lo que hace. Clases derivadas En C++, la herencia simple se realiza tomando una clase existente y derivando nuevas clases de ella. La clase derivada hereda las estructuras de datos y funciones de la cla se original. Además, se pueden añadir nuevos miembros a las clases derivadas y los miembros heredados pueden ser modificados. Una clase utilizada para derivar nuevas clases se denomina clase base, clase padre, superclase o ascendiente. Una clase creada de otra clase se denomina clase derivada o subclase. Se pueden construir jerarquías de clases, en las que cada clase sirve como padre o raíz de una nueva clase. Conceptos fundamentales de derivación C++ utiliza un sistema de herencia jerárquica. Es decir, se hereda una clase de otra, creando nuevas clases a partir de las clases ya existentes. Sólo se pueden heredar clases, no funciones ordinarias ni variables, en C++. Una clase derivada hereda todos los miembros dato excepto, miembros dato estáticos, de cada una de sus clases base. Una clase derivada hereda las funciones miembro de su clase base. 1

description

Herencia en C#

Transcript of Herencia

Page 1: Herencia

7/21/2019 Herencia

http://slidepdf.com/reader/full/herencia-56da74b8bc39f 1/5

Introducción

Una de las propiedades más importantes de la Programación Orientada a Objetos es la abstracción de datos.

Esta propiedad se manifiesta esencialmente en la encapsulación, que es la responsable de gestionar la

complejidad de grandes programas al permitir la definición de nuevos tipos de datos: las clases.

Sin embargo, la clase no es suficiente por sí sola para soportar diseño y programación orientada a objetos. Senecesita un medio para relacionar unas clases con otras. Un medio son las clases anidadas, pero sólo se

resuelve parcialmente el problema, ya que las clases anidadas no tienen las características requeridas para

relacionar totalmente una clase con otra. Se necesita un mecanismo para crear jerarquías de clases en las que

la clase A sea afín a la clase B, pero con la posibilidad de poder añadirle también características propias. Este

mecanismo es la herencia.

La herencia es, seguramente, la característica más potente de la Programación Orientada a Objetos, después de

las clases.

Por herencia conocemos el proceso de crear nuevas clases, llamadas clases derivadas, a partir de una clase

base.

En C++ la herencia se manifiesta con la creación de un tipo definido por el usuario (clase), que puede heredar

las características de otra clase ya existente o derivar las suyas a otra nueva clase. Cuando se hereda, las clases

derivadas reciben las características (estructuras de datos y funciones) de la clase original, a las que se pueden

añadir nuevas características o modificar las características heredadas. El compilador hace realmente una

copia de la clase base en la nueva clase derivada y permite al programador añadir o modificar miembros sin

alterar el código de la clase base.

La derivación de clases consigue la reutilización efectiva del código de la clase base para sus necesidades. Si

se tiene una clase base totalmente depurada, la herencia ayuda a reutilizar ese código en una nueva clase. No

es necesario comprender el código fuente de la clase original, sino sólo lo que hace.

Clases derivadas

En C++, la herencia simple se realiza tomando una clase existente y derivando nuevas clases de ella. La clase

derivada hereda las estructuras de datos y funciones de la clase original. Además, se pueden añadir nuevos

miembros a las clases derivadas y los miembros heredados pueden ser modificados.

Una clase utilizada para derivar nuevas clases se denomina clase base, clase padre, superclase o ascendiente.

Una clase creada de otra clase se denomina clase derivada o subclase.

Se pueden construir jerarquías de clases, en las que cada clase sirve como padre o raíz de una nueva clase.

Conceptos fundamentales de derivación

C++ utiliza un sistema de herencia jerárquica. Es decir, se hereda una clase de otra, creando nuevas clases a

partir de las clases ya existentes. Sólo se pueden heredar clases, no funciones ordinarias ni variables, en C++.

Una clase derivada hereda todos los miembros dato excepto, miembros dato estáticos, de cada una de sus

clases base.

Una clase derivada hereda las funciones miembro de su clase base.

1

Page 2: Herencia

7/21/2019 Herencia

http://slidepdf.com/reader/full/herencia-56da74b8bc39f 2/5

Esto significa que se hereda la capacidad para llamar a funciones miembro de la clase base en los objetos de la

clase derivada.

Los siguientes elementos de la clase no se heredan:

Constructores•

Destructores•

Funciones amigas•

Funciones estáticas de la clase•

Datos estáticos de la clase•

Operador de asignación sobrecargado•

Las clases base diseñadas con el objetivo principal de ser heredadas por otras se denominan clases abstractas.

Normalmente, no se crean instancias a partir de clases abstractas, aunque sea posible.

La herencia en C++

En C++ existen dos tipos de herencia: simple y múltiple. La herencia simple es aquella en la que cada clase

derivada hereda de una única clase. En herencia simple, cada clase tiene un solo ascendiente. Cada clase

puede tener, sin embargo, muchos descendientes.

La herencia múltiple es aquella en la cual una clase derivada tiene más de una clase base. Aunque el concepto

de herencia múltiple es muy útil, el diseño de clases suele ser más complejo.

Creación de una clase derivada

Cada clase derivada se debe referir a una clase base declarada anteriormente.

La declaración de una clase derivada tiene la siguiente sintaxis:

class clase_derivada:<especificadores_de_acceso> clase_base {...};

Los especificadores de acceso pueden ser: public, protected o private.

Clases de derivación

Los especificadores de acceso a las clases base definen los posibles tipos de derivación: public, protected y

private.

El tipo de acceso a la clase base especifica cómo recibirá la clase derivada a los miembros de la clase base.

Si no se especifica un acceso a la clase base, C++ supone que su tipo de herencia es privado.

− Derivación pública (public). Todos los miembros public y protected de la clase base son accesibles en la

clase derivada, mientras que los miembros private de la clase base son siempre inaccesibles en la clase

derivada.

− Derivación privada (private). Todos los miembros de la clase base se comportan como miembros privados

de la clase derivada. Esto significa que los miembros public y protected de la clase base no son accesibles más

que por las funciones miembro de la clase derivada. Los miembros privados de la clase siguen siendo

inaccesibles desde la clase derivada.

2

Page 3: Herencia

7/21/2019 Herencia

http://slidepdf.com/reader/full/herencia-56da74b8bc39f 3/5

− Derivación protegida (protected). Todos los miembros public y protected de la clase base se comportan

como miembros protected de la clase derivada. Estos miembros no son, pues, accesibles al programa exterior,

pero las clases que se deriven a continuación podrán acceder normalmente a estos miembros (datos o

funciones).

Constructores y destructores en herencia

Una clase derivada puede tener tanto constructores como destructores, aunque tiene el problema adicional de

que la clase base puede tomar ambas funciones miembro especiales.

Un constructor o destructor definido en la clase base debe estar coordinado con los encontrados en una clase

derivada. Igualmente importante es el movimiento de valores de los miembros de la clase derivada a los

miembros que se encuentran en la base.

En particular, se debe considerar cómo el constructor de la clase base recibe valores de la clase derivada para

crear el objeto completo.

Si un constructor se define tanto para la clase base como para la clase derivada, C++ llama primero al

constructor base. Después que el constructor de la base termina sus tareas, C++ ejecuta el constructor

derivado.

Cuando una clase base define un constructor, éste se debe llamar durante la creación de cada instancia de una

clase derivada, para garantizar la buena inicialización de los datos miembro que la clase derivada hereda de la

clase base.

En este caso la clase derivada debe definir a su vez un constructor que llama al constructor de la clase base

proporcionándole los argumentos requeridos.

Un constructor de una clase derivada debe utilizar un mecanismo de pasar aquellos argumentos requeridos por

el correspondiente constructor de la clase base.

derivada::derivada(tipo1 x, tipo2 y):base (x,y) {...}

Otro aspecto importante que es necesario considerar es el orden en el que el compilador C++ inicializa las

clases base de una clase derivada. Cuando El compilador C++ inicializa una instancia de una clase derivada,

tiene que inicializar todas las clases base primero.

Por definición, un destructor de clases no toma parámetros. Al contrario que los constructores, una función

destructor de una clase derivada se ejecuta antes que el destructor de la clase base.

Redefinición de funciones miembro heredadas

Se puede utilizar funciones miembro en una clase derivada que tengan el mismo nombre que otra de una clase

base.

La redefinición de funciones se realiza mediante funciones miembro sobrecargadas en la clase derivada. Una

función miembro redefinida oculta todas las funciones miembro heredadas del mismo nombre. Por tanto

cuando en la clase base y en la clase derivada hay una función con el mismo nombre en las dos, se ejecuta la

función de la clase derivada.

Herencia múltiple

3

Page 4: Herencia

7/21/2019 Herencia

http://slidepdf.com/reader/full/herencia-56da74b8bc39f 4/5

Es la propiedad con la cual una clase derivada puede tener más de una clase base. Es más adecuada para

definir objetos que son compuestos, por naturaleza, tales como un registro personal, un objeto gráfico.

Sólo es una extensión de la sintaxis de la clase derivada. Introduce una cierta complejidad en el lenguaje y el

compilador, pero proporciona grandes beneficios.

class ejemplo: private base1, private base2 {...};

La aplicación de clases base múltiple introduce un conjunto de ambigüedades a los programas C++.

Una de las más comunes se da cuando dos clases base tienen funciones con el mismo nombre, y sin embargo,

una clase derivada de ambas no tiene ninguna función con ese nombre.

¿Cómo acceden los objetos de la clase derivada a la función correcta de la clase base?

El nombre de la función no es suficiente, ya que el compilador no puede deducir cuál de las dos funciones es

la invocada.

Si se tiene una clase C que se deriva de dos clases base A y B, ambas con una función mostrar() y se define un

objeto de la clase C: C objetoC, la manera de resolver la ambigüedad es utilizando el operador de resoluciónde ámbito:

objetoC.A::mostrar(); //se refiere a la versión de //mostrar() de la clase A

objetoC.B::mostrar(); //se refiere a la versión de //mostrar() de la clase B

Constructores y destructores en herencia múltiple

El uso de funciones constructor y destructor en clases derivadas es más complejo que en una clase simple. Al

crear clases derivadas con una sola clase base, se observa que el constructor de la clase base se llama siempre

antes que el constructor de la clase derivada.

Además se dispone de un mecanismo para pasar los valores de los parámetros necesarios al constructor base

desde el constructor de la clase derivada. Así, la sentencia siguiente pasa el puntero a carácter x y el valor del

entero y a la clase base:

derivada (char *x, int y, double z): base(x,y)

Este método se expande para efectuar más de una clase base. La sentencia:

derivada (char *x,int y, double z): base1(x),base2(y)

Llama al constructor base1 y pasa el valor de cadena de caracteres x y al constructor base2 le proporciona un

valor entero y. Como con la herencia simple, los constructores de la clase base se llaman antes de que se

ejecuten al constructor de la clase derivada. Los constructores se llaman en el orden en que se declaran las

clases base.

De modo similar, las relaciones entre el destructor de la clase derivada y el destructor de la clase base se

mantiene. El destructor derivado se llama antes de que se llame a los destructores de cualquier base. Los

destructores de las clases base se llaman en orden inverso al orden en que los objetos base se crearon.

Herencia repetida

4

Page 5: Herencia

7/21/2019 Herencia

http://slidepdf.com/reader/full/herencia-56da74b8bc39f 5/5

La primera regla de la herencia múltiple es que una clase derivada no puede heredar más de una vez de una

sola clase, al menos no directamente. Sin embargo, es posible que una clase se pueda derivar dos o más veces

por caminos distintos, de modo que se puede repetir una clase. La propiedad de recibir por herencia una

misma clase más de una vez se conoce como herencia repetida.

Clases base virtuales

Una clase base virtual es una clase que es compartida por otras clases base con independencia del número de

veces que esta clase se produce en la jerarquía de derivación. Suponer, por ejemplo, que la clase T se derivade las clases C y D cada una de las cuales se deriva de la clase A. Esto significa que la clase T tiene dos

instancias de A en su jerarquía de derivación. C++ permite instancias múltiples de la misma clase base. Sin

embargo, si sólo se desea una instancia de la clase A para la clase T, entonces se debe declarar A como una

clase base virtual.

Las clases base virtuales proporcionan un método de anular el mecanismo de herencia múltiple, permitiendo

especificar una clase que es una clase base compartida.

Una clase derivada puede tener instancias virtuales y no virtuales de la misma clase base.

5