Está en la página 1de 12

UNIVERSIDAD MILITAR NUEVA GRANADA

DEPARTAMENTO DE TECNOLOGÍAS DEL CONOCIMIENTO


PROGRAMACIÓN II
HERENCIA

10 HERENCIA

Introducción

Durante las primeras unidades se estudiaron los tipos abstractos de datos y los
principales conceptos de POO, así como su implementación en lenguaje C++ a través
de las clases, pero no se trató con suficiente profundidad uno de los conceptos más
importantes de un lenguaje oriento a objetos, la herencia.

En esta unidad se estudia de manera detallada esta propiedad y la manera como


permite definir nuevas clases utilizando como base clases ya existentes, lo que
promueve la reutilización del software y su producción de manera confiable, eficiente
y adaptable.

Objetivo General

Presentar la herencia y sus principales características, como una forma de


reutilización de software.

Objetivos específicos

- Conocer la herencia como uno de los conceptos principales de la POO.


- Comprender la manera en que la herencia promueve la reutilización del
software.
- Estudiar las jerarquías de herencia y comprender las ideas relacionadas con las
clases base y las clases derivadas.
- Estudiar los diferentes tipos de herencia.

10.1 CLASES BASE Y DERIVADAS

La Programación Orientada a Objetos (POO) es un método de implementación de


programas que desarrolla clases con el fin de representar los objetos del mundo real,
y estas clases se relacionan entre por medio de jerarquías de herencia. Es así como
la herencia se convierte en uno de los tres conceptos más importantes de esta

Programación II Herencia Página 1


metodología y permite a los programadores implementar programas más compactos,
seguros, fáciles de depurar y corregir y versátiles.

La herencia permite utilizar clases existentes, llamadas clases base, para crear nuevas
clases,

conocidas como clases derivadas. A continuación se estudian estos conceptos y se


revisan algunos ejemplos de aplicación.

10.1.1 DEFINICIÓN DE HERENCIA Y CARACTERÍSTICAS PRINCIPALES

La herencia es la propiedad que permite definir nuevas clases usando como base las
clases ya existentes, es decir, reutilizar el código ya desarrollado para reducir el
código redundante en los nuevos componentes de clases. La herencia es una
herramienta poderosa que proporciona un marco adecuado para la producción de
software confiable, adaptable y reutilizable, disminuyendo costos y tiempo en su
desarrollo.

La propiedad de herencia se basa en la aplicación de este concepto en el mundo real,


en el cual podemos ver, por ejemplo, que los animales se dividen en mamíferos,
anfibios, reptiles, aves, etc., los vehículos se pueden dividir en automóviles,
motocicletas, camiones, buses, etc., y un sin número de ejemplos en los cuales el
principio fundamental es que en cada una de las divisiones se comparten ciertas
características comunes y se añaden otras características especiales; así, por
ejemplo, las aves son animales y además cuentan con plumas y pueden volar, los
mamíferos son animales y además amamantan a sus crías; por otro lado, los
automóviles son vehículos, tienen un motor y ruedas, cuentan con cuatro de ellas, a
diferencia de las motocicletas, que también son vehículos y tienen motor pero cuentan
con solo dos ruedas.

La utilización de esta propiedad supone la diferencia fundamental entre un lenguaje


de programación orientado a objetos y uno basado en objetos o estructurado.

En la herencia, a la clase existente se le denomina clase base, mientras que a la nueva


clase, que hereda las características y comportamientos de la clase base, se le conoce
como clase derivada.

Las clases derivadas, además, pueden añadir sus propios datos y comportamientos o
cambiar aquellos elementos de la clase base que necesitan sean diferentes.

Evidentemente, la clase base y la clase derivada tienen código (datos y

Programación II Herencia Página 2


comportamientos) comunes, y si se creará la clase derivada de modo independiente,
se duplicaría mucho de lo que se hizo para la clase base. La herencia evita este
inconveniente y promueve la reutilización del software.

10.1.2 DECLARACIÓN DE CLASES DERIVADAS

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

//Sintaxis para la declaración de una clase derivada class <Nombre de la clase

derivada> : <Tipo de herencia> <Nombre de la clase base>

{ public:

//Sección públic

private:

//Sección privada …

};
En la declaración anterior los dos puntos (:) son el símbolo para derivación o herencia
y el tipo de herencia puede ser public, private o protected, que en general determina
qué especificador de acceso a miembro tendrán, en la clase derivada, los miembros
que se heredaron de la clase base, como se explicará más adelante; si no se especifica
ningún tipo de herencia, por defecto se asigna el tipo de herencia private. Dentro de
los tipos de herencia aparece el tipo protected, que es un especificador de acceso a
miembro adicional que se utiliza solamente en el caso de trabajar con herencia.

Cuando se implementa la herencia, la clase derivada hereda todas las funciones


miembro y dato miembro de la clase base, excepto el constructor, el destructor y las
funciones amigas. Por esto es necesario definir un constructor en la clase derivada
que puede o no tener de manera explícita el llamado al constructor de la clase base
para que se inicialicen los datos miembro que se heredaron en la clase derivada.

A continuación se presenta un ejemplo en el cual se declara una clase base Vector2D,


con datos miembro x y y, y la definición de su constructor, y una clase derivada
vector3D con un dato miembro adicional z, e igualmente la definición de su
constructor, además de las funciones miembro típicas.

Programación II Herencia Página 3


//Declaración de la clase vector2D

class Vector2D{

public:

Vector2D(double=0, double=0);

void setVector2D(double, double);

double getx(); double gety();

void imprimir(); double

magnitudVector2D();

protected:

double x;

double y;

};

//Definición del constructor Vector2D Vector2D::

Vector2D (double l, double a){

x=l;

y=a;

//Definición de la clase derivada Vector3D class Vector3D:public Vector2D { public:

Vector3D (double=0, double=0, double=0);

void setz(double); double getz();

void imprimirVector3D(); double

magnitudVector3D ();

private:

double z;

protected:

Programación II Herencia Página 4


};

//Definición del constructor Vector3D

Vector3D:: Vector3D(double l, double a, double f)

x=l; //inicialización de los datos miembro protected heredados de Vector2D

y=a;

z=f;

En el ejemplo se puede ver que, a través de la notación de herencia, la clase Vector3D


hereda los datos y funciones de la clase Vector2D, sin necesidad de volver a definirlos.
También es evidente que en el constructor de la clase Vector3D se inicializan los datos
miembro heredados, x y y teniendo en cuenta que son declarados dentro del
especificador protected. Aunque no hay una llamada explicita al constructor de la
clase base Vector2D, el compilador efectúa este llamado implícitamente para
inicializar los datos heredados, una vez se empieza a ejecutar el constructor de
Vector3D.

El tipo de herencia utilizado en el ejemplo es public; adelante se explicará con más


detalle cada tipo de herencia.

10.1.3 MIEMBROS PROTEGIDOS (PROTECTED)

Durante la unidad 2 se estudiaron dos especificadores de acceso a miembro, public y


private, que definían como era el acceso a cada uno de los miembros de la clase, por
ejemplo, los miembros privados solo se pueden acceder a través de las funciones
miembro de la clase y los miembros públicos son accesibles desde cualquier parte
donde el objeto se encuentre al alcance. Los miembros protected o protegidos,
introducidos en el numeral anterior y apenas nombrados en las unidades anteriores,
establecen un nivel intermedio de acceso ya que, además de ser accesibles desde
cualquier miembro de la clase, también se pueden acceder desde cualquier miembro
de las clases derivadas. Por esta razón solo cobran importancia cuando se utiliza la
herencia.

Programación II Herencia Página 5


En el ejemplo anterior se puede ver que los datos miembros de la clase Vector2D se
especifican como protectec, y en el constructor de la clase derivada Vector3D se
acceden directamente para su inicialización. Esta es una ventaja en algunos casos,
pero en general se recomienda utilizar el especificador private para los datos miembro
de una clase y así promover el encapsulamiento de la información. A continuación se
muestra la definición del constructor de la clase derivada Vector3D en el caso en que
los datos de la clase Vector2D se declararan como privados:

//Definición del constructor Caja en el caso de que los datos heredados fueran private

Vector3D:: Vector3D (double l, double a, double f)

: Vector2D (l,a) //Llamado al constructor de la clase


base para inicializar los datos

{ //dentro de lo que se conoce como lista de inicialización de miembros

z=f;

Si los datos heredados por la clase Vector3D son privados, y teniendo en cuenta que
los datos privados solo se pueden acceder desde las funciones miembro de la clase,
es necesario hacer un llamado a alguna función miembro de la clase Vector2D dentro
del constructor de Vector3D para poder inicializarlos, en este caso se hace un llamado
al constructor de Vector2D, dentro de lo que se conoce como una lista de inicialización
de miembros (después del paréntesis de los parámetros se escribe el operador dos
puntos (:) y se llama la función correspondiente).

10.2 TIPOS DE HERENCIA

Existen diferentes clasificaciones para la herencia, como ya se mencionó


anteriormente, según el especificador de acceso a miembro, la herencia se clasifica
en public, private y protected, a continuación se define cada una de ellas:

- Herencia public: Este tipo de herencia especifica que los datos y funciones
miembro heredados de la clase base conservan el mismo especificador de
acceso en la clase derivada, es decir, los miembros públicos de la clase base

Programación II Herencia Página 6


son públicos en la clase derivada, los miembros protegidos en la clase base
continúan siendo protegidos en la clase derivada, y los miembros privados en
la clase base siguen siendo privados en la clase derivada. Este tipo de herencia
es el más utilizado.
- Herencia protected: Con este tipo de herencia se define que los miembros
públicos y protegidos de la clase base se especifican como protegidos en la
clase derivada, y los datos privados de la clase base siguen siendo privados en
la clase derivada. Su uso no es muy común, salvo en aplicaciones muy
específicas.
- Herencia private: Cuando se utiliza este tipo de herencia los miembros públicos
y protegidos de la clase base, se especifican como privados en la clase derivada.
Su uso no es muy común, salvo en aplicaciones muy específicas.

En la siguiente tabla se resume el especificador de acceso a miembro para la clase


derivada, según el tipo de herencia:
Tipo de Acceso Acceso
Herencia miembro miembro
clase base clase
derivada
public public Public

protected Protected

private Private

protected public Protected

protected Protected

private Private

private public Private

protected Private

private Private

Programación II Herencia Página 7


Una segunda clasificación para la herencia, según el número de clases base, la divide
en simple y múltiple:

- Herencia simple: es un tipo de herencia en el cual una clase derivada hereda


datos y funciones de una sola clase base. Es el tipo de herencia de más amplia
utilización. Su sintaxis es la misma que se ha utilizado hasta ahora.
- Herencia múltiple: es un tipo de herencia en el cual una clase derivada hereda
datos y funciones de más de una clase base. Su sintaxis es la siguiente:
//Sintaxis para la declaración de un herencia múltiple class <clase

derivada> : <Tipo> <clase base1>, <Tipo> <clase base2>, <Tipo>

<clase base2>,…

{
public:
//Sección pública

private:

//Sección privada

};

Este tipo de herencia presenta inconvenientes relacionados con la ambigüedad


por el uso de nombres de miembros idénticos en diferentes clases base y, por
consiguiente, la preponderancia o dominación de estos dentro de la clase
derivada. En general no es muy utilizada, salvo aplicaciones muy específicas.

10.3 TIPOS DE RELACIÓN

Cuando en un programa orientado a objetos se crean diferentes clases, cuyas


instancias u objetos interactúan entre sí, estas clases se relacionan de diferentes
formas dependiendo del vínculo o la forma de declaración que se utilice.

Programación II Herencia Página 8


Cuando se utilizan la herencia, se establece una relación “es un”, en donde un objeto
de una clase derivada también es un objeto de la clase base. Por ejemplo, al crear un
jerarquía de clases de figuras geométricas con cuadrilátero como clase base, y
cuadrado, rectángulo, rombo y trapecio como clases derivadas, un objeto de la clase
trapecio también “es un” objeto de la clase cuadrilátero. De igual forma ocurre con el
ejemplo mencionado anteriormente en el que un ave también es un animal.

Esta característica se debe tener en cuenta siempre que se vaya a establecer una
jerarquía de herencia para un programa orientado a objetos.

En cambio, cuando se utiliza un objeto de una clase determinada como dato miembro
de otra clase, se establece una relación ”tiene un”, en la que un objeto hace parte de
la implementación de otra clase, sin entregar sus datos y funciones para que hagan
parte de la definición de la nueva clase. Este tipo de relación se conoce comúnmente
como Composición.

Por ejemplo, si se quiere implementar la clase vehículo, podrían utilizarse objetos de


las clases motor, suspensión, carrocería, etc., como sus miembros, es decir, un objeto
de la clase vehículo “tiene un motor”, suspensión o carrocería.
//Ejemplo de composición con la clase vehículo y motor

//Declaración de la

clase Motor class

Motor{ public:

Motor();

void setMotor(double,

double); double

getPotencia(); double

getCilindraje(); void

imprimir(); double

torqueMotor();

private:

double potencia;

double cilindraje;

Programación II Herencia Página 9


};

//Definición de la clase

Vehiculo class

Vehiculo{ public:

Vehiculo(double,

Motor); void

setPrecio(double);

double

getPrecio(); void

imprimirVehiculo();

private:

double precio;

Motor VS1000;

};

Igualmente en programación orientada a objetos se presentan otros tipos de


relaciones, por ejemplo la relación “usa un” se presenta cuando una función utiliza o
recibe como parámetro un objeto de una clase, y a partir de sus datos obtiene algún
resultado específico.

Resumen
La herencia es una propiedad que permite al programador crear nuevas clases a partir
de clases ya existentes. A las clases existentes se les conoce como clases base y a
las nuevas clases se les conoce como clases derivadas.

Existen diferentes tipos de herencia. Según el número de clases base se puede


clasificar en herencia simple, cuando solo hay una clase base y herencia múltiple,
cuando la clase derivada hereda de más de una clase base. Según el especificador de
acceso a miembro, la herencia se puede clasificar en public, private y protected: la
herencia public mantiene el especificador de acceso de cada miembro de la clase base,
en la clase derivada. Es la más utilizada.

Programación II Herencia Página 10


Además de la herencia, que establece una relación “es un” entre las clases, existe
otro tipo de relación entre clases conocida como composición, en la que un objeto de
una clase es miembro de otra clase, por lo tanto se puede decir que un objeto de una
clase “tiene un” objeto de otra clase.

La herencia es una característica fundamental de un programa orientado a objetos y


además permite la reutilización del software, que hace posible la implementación de
programas robustos, confiables y con menores requerimientos de costos y tiempo.

Actividades complementarias

- Implementar una clase Automóvil dentro de una jerarquía de herencia múltiple.


Considere que, además de ser un Vehículo, un automóvil es también una
comodidad, un medio de transporte, etc. Automóvil debe tener al menos tres
clases base y al menos tres clases derivadas.
- Para definir un punto en un sistema de coordenadas de dos dimensiones es muy
común utilizar la forma (x,y) llamada coordenadas rectangulares. Construya una
clase llamada Punto que describa puntos en esta forma. Escriba un constructor y
las respectivas funciones para establecer y obtener los datos.
Construya una clase derivada Circulo a partir de la clase Punto, que contenga el
miembro adicional radio, para especificar el radio del círculo. Además funciones
miembro que permitan calcular el área y la circunferencia del círculo, que están dadas
por las siguientes ecuaciones:

CircunferenciaCirculo 2 r AreaCirculo r2

Construya una clase derivada Cilindro a partir de la case Circulo, que contenga el
miembro adicional h, para especificar la altura del cilindro. Además funciones
miembro que permitan calcular el área y el volumen del cilindro, que están dadas por
las siguientes ecuaciones:

AreaCilindro 2 r2 2 rh VolumenCilindro r2h

Lecturas recomendadas

SMITH JO ANN, C++ Programación Orientada a Objetos. Editorial Paraninfo, 1999.


Páginas 91 a 148.

Programación II Herencia Página 11


DIETEL, H. M., DIETEL, P. J. Cómo programar en C++. Editorial Pearson Education,
4ª Edición 2003. Páginas 609 a 648.

JOYANES, Luis J., Programación en C++, Algoritmos, estructuras de datos y objetos.


Editorial Mc Graw Hill, 2ª Edición 2002. Páginas 479 a 497.

Programación II Herencia Página 12

También podría gustarte