Cómo funciona la herencia de clases

Herencia de Clases

La herencia de clases es uno de los conceptos básicos de la programación orientada a objetos. Decir que una clase hereda de otra quiere decir que esa clase obtiene los mismos métodos y propiedades de la otra clase. Permitiendo de esta forma añadir a las características heredadas las suyas propias.

La herencia es, después de la agregación o composición, el mecanismo más utilizado para alcanzar algunos de los objetivos más preciados en el desarrollo de software como lo son la re-utilización y la extensibilidad. A través de ella los diseñadores pueden crear nuevas clases partiendo de una clase o de una jerarquía de clases preexistente evitando con ello el rediseño, la modificación y verificación de la parte ya implementada. La herencia facilita la creación de objetos a partir de otros ya existentes e implica que una subclase obtiene todo el comportamiento y eventualmente los atributos de su superclase.

Es la relación entre una clase general y otra clase más específica. Por ejemplo: Si declaramos una clase párrafo derivada de una clase texto, todos los métodos y variables asociadas con la clase texto, son automáticamente heredados por la subclase párrafo.

 

Tipos de herencia de clases

Existen dos tipos de herencia:

  • Herencia por especialización
  • Herencia por generalización

 

Herencia por especialización

Una herencia por especialización es la que se realiza cuando necesitamos crear una clase nueva que disponga de las mismas características que otra pero que le añada funcionalidades. Por ejemplo, si tenemos una clase que genera un botón simple, y necesitamos crear un botón que sea igual que el anterior pero que además añada un efecto al ser ciclado.

 

Herencia por generalización

La herencia por generalización es la que realizamos cuando tenemos muchas clases que comparten unas mismas funcionalidades y por homogeneizar las partes comunes se decide crear una clase que implemente toda esa parte común y se dejan solo las partes especificas en cada clase. Por ejemplo, si tenemos clases para dibujar formas geométricas todas ellas

 

Jerarquía, clases base y clases derivadas

Cada nueva clase obtenida mediante herencia se conoce como clase derivada, y las clases a partir de las cuales se deriva, clases base. Además, cada clase derivada puede usarse como clase base para obtener una nueva clase derivada. Y cada clase derivada puede serlo de una o más clases base. En este último caso hablaremos de derivación múltiple.

Esta propiedad nos permite encapsular diferentes partes de cualquier objeto real o imaginario, y vincularlo con objetos más elaborados del mismo tipo básico, que heredarán todas sus características. Lo veremos mejor con un ejemplo.

  • Derivar clases

La forma general de declarar clases derivadas es la siguiente:

En seguida vemos que para cada clase base podemos definir dos tipos de acceso, public o private. Si no se especifica ninguno de los dos, por defecto se asume que es private.

  • public: los miembros heredados de la clase base conservan el tipo de acceso con que fueron declarados en ella.

De momento siempre declararemos las clases base como public, al menos hasta que veamos la utilidad de hacerlo como privadas.

  • private: todos los miembros heredados de la clase base pasan a ser miembros privados en la clase derivada.

 

Veamos un ejemplo sencillo basado en la idea del punto anterior:

Podrás ver que hemos declarado los datos miembros de nuestras clases como protected. En general es recomendable declarar siempre los datos de nuestras clases como privados, de ese modo no son accesibles desde el exterior de la clase y además, las posibles modificaciones de esos datos, en cuanto a tipo o tamaño, sólo requieren ajustes de los métodos de la propia clase.

 

Ejemplo de código

Generalmente una clase representa de manera formal un concepto de la realidad. Por ejemplo podríamos tener un objeto llamado jose que es una instancia de la clase obrero. Pero un obrero es a la vez un asalariado, y en un nivel de abstracción mayor un asalariado es una persona.

Este tipo de relaciones de es un se intentan representar en C++ mediante la definición de herencia, que define formalmente la relación es un entre las clases.
  • persona
  • asalariado
  • obrero

De la misma manera, podríamos tener otro objeto pedro que es una instancia de la clase medico. Cómo pedro trabaja para un laboratorio de productos famaceúticos, es también un asalariado, pero no un obrero. De esta manera nos queda una relación en el nivel superior de nuestra jerarquía de clases tendríamos que: medico y obrero son asalariados y a su vez personas.

  • persona
  • asalariado
  • obrero
  • medico

Si bien podemos seguir la jerarquía de clases hacia arriba diciendo “es un” hay que tener en cuenta que no podemos decir ni que un obrero es un medico, ni que un medico es un obrero, aunque ambos sean asalariado y persona.En el ejemplo siguiente vamos a ver como se podría llegar a armar esta estructura y vemos como se re aprovechan las definiciones de las funciones miembro de las jerarquías superiores cuando no hace falta redefinirlas en las clases de jerarquías más bajas.