Herencia en Java

Publicado el 21 mayo 2013 por Cristian David Henao Hoyos @chenaooo
En esta ocasión vamos a profundizar un poco (desde el enfoque de programación, no teórico) en uno de los principales conceptos de programación orientada a objetos en java...............el concepto de Herencia, vamos a realizar un ejemplo practico para verificar su funcionamiento y aplicación en el desarrollo de software. 
Como se mencionó en la entrada anterior, básicamente mediante este concepto podemos obtener las características de una clase padre o de una jerarquía mayor dependiendo de nuestro árbol de herencia, en java definimos esta jerarquía mediante la palabra extends seguido del nombre de la clase a la que vamos a heredar, también se debe tener claro que solo se puede heredar de una sola clase pues el lenguaje no permite la Herencia múltiple (En Java por defecto todas las clases heredan de la clase Object, es decir, esta es la clase Padre de todas las clases en Java).
Requisitos.
Lo único que necesitamos para hacer el ejemplo practico es un entorno de desarrollo, conocer los conceptos de POO (vistos en la entrada anterior) y ganas de continuar :P para este caso usaremos el IDE Eclipse...........Empecemos.
El Ejemplo.
Conociendo el concepto de clases y objetos vamos a asumir que necesitamos construir una aplicación sobre los diferentes tipos de vehículos existentes, pero para esto necesitamos clasificarlos, en este caso trabajaremos con vehículos acuáticos y aéreos.

Teniendo como punto de partida la información anterior podemos empezar a definir nuestras clases, vamos a trabajar con vehículos acuáticos y vehículos aéreos, entonces......... cual es el factor común de estos 2 tipos?..............................................El factor común es que sin importar si es un avión o un barco, estamos hablando de vehículos, y ambos pueden compartir características comunes por esta razón la Clase principal de nuestro sistema sera la clase Vehiculo.

Partiendo de lo anterior podemos profundizar aun mas en nuestro árbol de herencia, sabemos que un barco o un avión son vehículos, pero será que esta información es suficiente???.......... sería correcto decir que ¿un barco es igual a un avión porque ambos son vehículos?..........definitivamente NO, ya que si bien descienden del mismo concepto de vehículo ambos tienen características propias que los diferencian, aquí es donde tenemos que pensar de forma general para poder definir un correcto árbol de herencia, por eso podemos decir que un barco además de descender de un vehículo, también desciende del tipo de vehículos Acuáticos los cuales tienen un conjunto de características comunes para cualquier vehículo acuático (sin olvidar que cada vehículo acuático puede tener sus características propias) y de la misma forma un avión desciende del tipo de vehículos Aéreos (con la misma lógica del anterior)............tenemos así nuestras clases Acuatico y Aereo que a su vez descienden de la clase Vehiculo, y son padres de cualquier vehículo en su jerarquía.

Al final tenemos definida nuestra estructura de clases (para este ejemplo no entraremos en detalles sobre las características a profundidad de cada clase, pero si alguna básica para resaltar el concepto) así:


Como vemos, la Clase Padre es Vehiculo, la cual tiene como hijas a las clases Acuatico y Aereo, estas a su vez son clases Padre de Barco, Velero, Avion y Helicoptero que a la vez son nietas de Vehiculo...Simple o ¿no?
Con esto ya tenemos una jerarquía de herencia definida, esto quiere decir que por ejemplo la clase Avion puede usar el método volar() de la clase Aereo, así como también usar el método transportar() de la clase Vehiculo, pues se encuentra en el mismo árbol de herencia, sin embargo no puede usar el método navegar() de la clase Acuatico, ya que no es de tipo Acuatico.
Teniendo nuestro diagrama definido, vamos a aplicar el concepto en Java.Vehiculo.Clase Padre.
/**
* @author HENAO
*
*/
public class Vehiculo {
public int modeloVehiculo;
public String nombreVehiculo="";
public String transportar(){
return "Metodo transportar de clase Vehiculo";
}
}


Acuatico.SubClase extiende de Vehiculo.

public class Acuatico extends Vehiculo{
public String nombreAcuatico="";
public String navegar(){
return "Método navegar de clase Acuatico";
}
}
Aereo.SubClase extiende de Vehiculo.
public class Aereo extends Vehiculo {
public String nombreAereo="";
public String volar(){
return "Método volar desde clase Aereo";
}
}
Barco.SubClase extiende de Acuatico.
public class Barco extends Acuatico {
public String prenderMotor(){
return "Método prenderMotor en clase Barco";
}
}
Velero.SubClase extiende de Acuatico.
public class Velero extends Barco{
public String izarVelas(){
return "Método izarVelas en clase Velero";
}
}
Clase Avion. 

SubClase extiende de Aereo.
public class Avion extends Aereo{
public String bajarTrenDeAterrizaje(){
return "Método bajarTrenDeAterrizaje en clase Avion";
}
}
Clase Helicoptero.
SubClase extiende de Aereo.
public class Helicoptero extends Aereo{
public String encenderHelices(){
return "Método encenderHelices en clase Helicoptero";
}
}

Como vemos seguido del nombre de la clase se tiene la palabra extends la cual indica que se extiende o hereda de la clase definida, así mismo todas las clases tienen al menos un método que representa la característica propia de la clase, para las clases hijas ese método define el proceso que solo ellas pueden realizar, para las clases padre, ese método define el proceso que es común o general para las clases hijas.


Ahora veremos como funciona la herencia en nuestra aplicación.
Creamos una clase Principal donde se realizarán las operaciones, podemos crear instancias de las clases y verificar el nivel de acceso que tenemos a las características tanto de nuestra clase como de nuestra Jerarquía de Herencia, así.

En la imagen vemos que tenemos una instancia de la clase Vehículo, esto lo podemos traducir como la creación del objeto miVehiculo de tipo Vehiculo, no olvidemos que esta clase es la clase padre, por eso al verificar los métodos disponibles (En Eclipse después del punto hacemos Ctrl+espacio) vemos que nos aparecen las características propias de la clase, asi como otros métodos de la clase Object (Recordemos que en java todas las clases heredan de Object) que también podemos usar.

Al crear otro objeto de la clase Acuatico y realizar el mismo proceso anterior, vemos que ahora tenemos no solo los métodos propios de la clase sino también los métodos y atributos de la clase Vehiculo.

Ahora miremos un objeto de las clases Hijas.


Al crear un objeto de la clase Barco vemos que ahora no solo tenemos las características de Barco sino también podemos hacer uso de las características de Acuatico y de Vehiculo.

Este mismo principio aplica para la otra parte de nuestra jerarquía (Vehículos Aéreos) donde como mencionamos anteriormente solo podemos acceder a los métodos y atributos disponibles para ese árbol de herencia.

Veamos todo nuestro código...

public class Principal {
/**
* @param args
*/
public static void main(String[] args) {

System.out.println("*********************************************************************");
System.out.println("* << CoDejaVu >> *");
System.out.println("* *");
System.out.println("*********************************************************************");
System.out.println();
System.out.println("-------------------<< Clase Padre Vehiculo >>-----------------------");
Vehiculo miVehiculo = new Vehiculo();
miVehiculo.nombreVehiculo="El Gran Transportador";
System.out.println("usando miVehiculo, nombreVehiculo : "+miVehiculo.nombreVehiculo);
System.out.println("usando miVehiculo llama a: "+miVehiculo.transportar());
System.out.println("--------------------------------------------------------------------");
System.out.println();
System.out.println("----------<< SubClase hija Acuatico Extiende de Vehiculo >>---------");
Acuatico miAcuatico= new Acuatico();
miAcuatico.nombreVehiculo="El Navegante";
System.out.println("usando miAcuatico, nombreVehiculo : "+miAcuatico.nombreVehiculo);
System.out.println("usando miAcuatico llama a : "+miAcuatico.transportar());
System.out.println("usando miAcuatico llama a : "+miAcuatico.navegar());
System.out.println("---------------------------------------------------------------------");
System.out.println();
System.out.println("-----<< SubClases hijas extienden de la Subclase Padre Acuatico>-----");
Barco miBarco=new Barco();
miBarco.nombreVehiculo="Titanic";
System.out.println("usando miBarco, nombreVehiculo : "+miBarco.nombreVehiculo);
System.out.println("usando miBarco llama a : "+miBarco.transportar());
System.out.println("usando miBarco llama a : "+miBarco.navegar());
System.out.println("usando miBarco llama a : "+miBarco.prenderMotor());
System.out.println();
Velero miVelero=new Velero();
miVelero.nombreVehiculo="Tormenta";
System.out.println("usando miVelero, nombreVehiculo : "+miVelero.nombreVehiculo);
System.out.println("usando miVelero llama a : "+miVelero.transportar());
System.out.println("usando miVelero llama a : "+miVelero.navegar());
System.out.println("usando miVelero llama a : "+miVelero.izarVelas());
System.out.println("---------------------------------------------------------------------");
System.out.println("----------<< SubClase hija Aereo Extiende de Vehiculo >>---------");
Aereo miAereo= new Aereo();
miAereo.nombreVehiculo="El Volador";
System.out.println("usando miAereo, nombreVehiculo : "+miAereo.nombreVehiculo);
System.out.println("usando miAereo llama a : "+miAereo.transportar());
System.out.println("usando miAereo llama a : "+miAereo.volar());
System.out.println("---------------------------------------------------------------------");
System.out.println();
System.out.println("-----<< SubClases hijas extienden de la Subclase Padre Aereo >-----");
Avion miAvion=new Avion();
miAvion.nombreVehiculo="El Condor";
System.out.println("usando miAvion, nombreVehiculo : "+miAvion.nombreVehiculo);
System.out.println("usando miAvion llama a : "+miAvion.transportar());
System.out.println("usando miAvion llama a : "+miAvion.volar());
System.out.println("usando miAvion llama a : "+miAvion.bajarTrenDeAterrizaje());
System.out.println();
Helicoptero miHelicoptero=new Helicoptero();
miHelicoptero.nombreVehiculo="El lobo del Aire";
System.out.println("usando miHelicoptero, nombreVehiculo : "+miHelicoptero.nombreVehiculo);
System.out.println("usando miHelicoptero llama a : "+miHelicoptero.transportar());
System.out.println("usando miHelicoptero llama a : "+miHelicoptero.volar());
System.out.println("usando miHelicoptero llama a : "+miHelicoptero.encenderHelices());
System.out.println("---------------------------------------------------------------------");
System.out.println();
System.out.println("--<< Propiedad de la clase Vehiculo usada por todas las clases Hijas >--");
System.out.println("nombre Vehiculo :"+miVehiculo.nombreVehiculo);
System.out.println("nombre Acuatico :"+miAcuatico.nombreVehiculo);
System.out.println("nombre Aereo :"+miAereo.nombreVehiculo);
System.out.println("nombre Barco :"+miBarco.nombreVehiculo);
System.out.println("nombre Velero :"+miVelero.nombreVehiculo);
System.out.println("nombre Avion :"+miAvion.nombreVehiculo);
System.out.println("nombre Helicoptero :"+miHelicoptero.nombreVehiculo);
System.out.println("---------------------------------------------------------------------");
}
}

Con este ejemplo hacemos el llamado a los métodos tanto propios como heredados de las clases padres, obteniendo el siguiente resultado.



Como vemos podemos acceder a los diferentes métodos desde otras clases, y si nos fijamos bien podemos identificar que siempre usamos la misma propiedad nombreVehiculo de la clase Vehiculo, lo hicimos usando objetos diferentes por tal razón el valor de la propiedad depende del asignado por cada objeto, convirtiéndose en un atributo del objeto y no de la clase como tal.
Conclusión
Podemos ver que la herencia va ligada a muchos otros conceptos, vimos el concepto de clase, el concepto de objetos entre otros, en este caso también es importante conocer el concepto de encapsulación ya que como compartimos características entre clases tenemos que estar seguros que la clase que accede puede usarlas, aunque mas adelante trataremos este tema a profundidad.........espero que esta entrada sea útil y fácil de entender......
También te podría Interesar. 
  • Conceptos Básicos de Programación Orientada a Objetos.
  • ¿ String Vrs StringBuffer Vrs StringBuilder ?
  • Comparando Fechas En Java
  • Tutorial Aplicaciones Web con Jboss Seam
  • Instalación del servidor de aplicaciones JBoss
  • Configuración Ambiente de Desarrollo... Descarga de Eclipse
  • Trabajando con SVN desde Eclipse

¿Hay algo que quieras anexar o comentar sobre esta entrada?  no dudes en hacerlo....