G.Bordel >Docencia >TAP Técnicas Actuales de Programación (curso 2010-2011)
desprotegido Intro. desprotegido Temario desprotegido Calendario desprotegido RPF desprotegido Recursos protegido Práctica protegido Gest. Alum.
tema_anterior Tema 4: Elementos relacionados con la orientación a objeto tema_siguiente
  1. Objetos y clases.
  2. Estructura de la definición de una clase.
  3. Herencia.
  4. Encapsulamiento (ámbitos de accesibilidad).
  5. El bloque static y los atributos static y final.
  6. Instanciación, inicialización y eliminación de objetos.[ejercicios]
  7. Clases y métodos abstractos.[ejercicios]
  8. Interfaces.[ejercicios]
  9. Polimorfismo.
  10. Arrays*.[ejercicios]
  11. Enumeraciones.

4.3- Herencia

Palabras reservadas en Java
abstractbooleanbreakbytecasecatch
charclassconst*continuedefaultdo
doubleelseextendsfinalfinallyfloat
forgoto*ifimplementsimportinstanceof
intinterfacelongnativenewpackage
privateprotectedpublicreturnshortstatic
strictfp**superswitchsynchronizedthisthrow
throwstransienttryvoidvolatilewhile

La herencia es un mecanismo que permite establecer una cierta relación entre clases que resulta de utilidad en dos sentidos: por un lado permite estructurar el conjunto de las clases dándole una cierta consistencia, y por otro permite un ahorro de esfuerzo de definición.

Visto desde el segundo punto de utilidad indicado, el hecho de que una clase A herede de otra B significa que en su definición se incluye automáticamente toda la definición de B sin necesidad de reescribirla. Para ello basta con utilizar en la declaración, tras el nombre de la clase, la palabra clave "extends" y el nombre de la clase B. Por tanto toda la definición de clase que se realice en A, se irá añadiendo a la ya realizada automáticamente. Los campos y métodos de A serán todos los de B mas los que se incluyan específicamente en su definición.

Visto desde el primer punto de utilidad indicado, el hecho de que una clase A herede de otra B significa que los objetos de esta clase A son objetos de un tipo específico dentro de los que define la clase B. Es decir todos los objetos definidos por la clase A pueden ser considerados como objetos de clase B, pero no al contrario. Para aclarar esto podemos concretar mediante un ejemplo: una clase "CuentaCorriente" puede heredar de otra denominada "CuentaBancaria" una serie de campos (como "saldo",etc) y de métodos (como "realizarMovimiento(*)", etc) añadiendo otros específicos (como bloquearCantidad(*), etc). Un objeto de clase "CuentaCorriente" puede considerarse tambien como de tipo "CuentaBancaria" ya que posee todas sus características, mientras que lo contrario no será necesariamente cierto. Pueden definirse otras clases que hereden de "CuentaBancaria" (como p.ej "CuentaDeAhorro") y que sean sub-clases distintas de la "CuentaCorriente".


Declaración de la clase CuentaCorriente como heredera de CuentaBancaria. En el gráfico se muestra esta relación de herencia y otra similar con la clase CuentaDeAhorro

Esta estructuración del conjunto de las clases en función de la herencia es un árbol, es decir, existe una clase "raiz" de la que parten una serie de ramas hacia sus clases herederas, que son a su vez raices de sub-arboles. Cada clase, con excepción de la raiz, tienen una y solo una clase "padre". En genral no resultará trivial el establecimiento de la herencia entre clases, ya que un determinado objeto puede presentar caracteristicas de mas de una clase (p.ej, "pájaro" puede heredar de "animal" al compartir características con el resto de animales, pero tambien puede heredar de "volador" al compartir características aplicables tanto a animales como a aparatos con capacidad para volar). Esto se resolvería permitiendo la herencia múltiple, como hacen otros lenguajes orientados a objetos (p.ej C++), pero en el planteamiento de Java se tuvo en cuenta que esta característica tiene más desventajas que beneficios y se optó por no admitirla. Las capacidades de la herencia múltiple se obtienen en Java mediante el mecanismo de los interfaces que se estudiará más adelante.

La clase raiz en Java se denomina Object, y se estudiará con detenimiento en un próximo capítulo. Como quiera que Object es la clase raiz de toda la estructura, quiere esto decir que el hecho de no explicitar una herencia en la definición de una clase (no poner "extends <clase>") no quiere decir que la clase este fuera de las relaciones de herencia, sino que tiene la herencia que podemos llamar "mínima" y su clase padre es directamente la clase Object.

Volviendo al aspecto "mecánico" de la herencia, decíamos que una clase A que heredaba de B podía definir nuevos elementos a los ya adquiridos automáticamente. Hay que concretar aquí que tambien es posible que las definiciones específicas coincidan en cierto modo con las heredadas, y en tal caso se hablará de una redefinición de la característica, es decir se "anula" la característica heredada que se ve sustituida por la nueva definición. Es lo que en la terminología de la orientación a objeto se denomina "sobreescritura". Esto permite que no sólo se añadan características particulares a la nueva clase, sino que se particularicen características generales que pertenecian a la clase padre. Pongamos un ejemplo: volviendo a las cuentas bancarias, podemos tener un método reintegro(*) en la clase CuentaBancaria que heredarán todas sus subclases, pero dependiendo del tipo de cuenta, la política de reintegros puede ser distinta (p.ej. permitiendo o no descubiertos en la cuenta), de modo que si cada subclase define de nuevo el método de un modo específico, se sustituye al heredado. Un método se considera reescrito cuando coinciden el nombre, tipo de retorno y parámetros; otras características pueden variar pero, una vez más, tenemos que dejar pendiente para más adelante el estudio de estos detalles.

Siguiente punto: 4.4- Encapsulamiento (ámbitos de accesibilidad)


Plataforma de soporte a curso y contenidos (c) German Bordel 2005.