Herencia

La herencia es un tipo muy importante de relación entre objetos. En una relación de herencia, una clase recibe las propiedades y comportamiento de otra como si fuesen suyas y, al mismo tiempo, puede agregar las propias.

Veamos esto con un ejemplo. Supongamos que estamos desarrollando una aplicación que necesita hacer cálculos de superficie sobre distintas figuras geométricas, es decir, vamos a tener objetos como Círculo, Cuadrado, Trapecio, etcétera. Dado el requerimiento que tenemos, todos los objetos presentarán un comportamiento en común: calcular su superficie. Lo que podemos hacer entonces es definir una clase llamada Figura y establecer una relación de herencia entre esta clase y cada una de las figuras particulares. Le asignamos el método de cálculo de superficie a la clase Figura y, mediante la relación de herencia, las demás clases tendrán este comportamiento como heredado. Decimos entonces que las clases Cuadrado, Trapecio, etcétera, heredan de la clase Figura.

Así como el uso define una relación usa-a, y la composición define una relación se-compone-de, la herencia se conoce como una relación es-un. Siguiendo con el ejemplo de las figuras, decimos que un círculo es una figura, un cuadrado es una figura, y así con todos. Cuando una clase B hereda de una clase A, se dice que la clase A es la clase padre o clase base, y la clase B es la clase hija, heredera o deri- vada. En el ejemplo anterior, entonces, la clase Figura es la clase base, y las de- más, sus clases derivadas.

DISEÑAR PENSANDO EN OBJETOS La herencia tiene una gran potencia para escribir código reutilizable, flexible y mantenible. Por eso, durante el análisis del problema y durante el posterior diseño de las clases, se debe prestar especial atención a identificar relaciones de herencia para aprovechar sus virtudes. Conocer algunos patrones de diseño puede ayudar también a identificar relaciones de herencia, aun en clases no concretas.

La relación de herencia no se limita a un solo nivel, es decir, que una clase deriva- da de otra puede a su vez ser la base de una tercera clase, formando así una estructura jerárquica o de árbol. Además, en escenarios de múltiples niveles, la relación de herencia es transitiva, esto es, si una clase C hereda de B, que a su vez hereda de A, todo el comportamiento y las propiedades de A pertenecen también a C.

A partir del ejemplo anterior, podemos apreciar que la relación de herencia provee un mecanismo para lograr uno de los objetivos más importantes de la programación orientada a objetos, la reutilización de código. ¿Cómo se entiende esto? Supongamos que de la clase Figura hereda una clase Cuadrilátero, que tiene propiedades para representar la longitud de cada uno de los lados. Si de la clase Cuadrilátero derivan Rombo, Trapecio y Rectángulo, en estas nuevas clases ya no tendremos que escribir el código de la propiedad, es decir, hemos reutilizado código que ya estaba escrito.

Mediante la herencia, podemos definir una jerarquía de clases, donde cada clase derivada hereda el comportamiento y las propiedades de su clase base.

Además de la reutilización de código, la herencia provee otras aplicaciones útiles, como son la extensión y la redefinición de clases. Veamos de qué se trata, en nuestra próxima entrega.