Herencia en Java
La herencia es uno de los cuatro pilares de la Programación Orientada a Objetos. En esta entrada presentaré los conceptos básicos de la herencia en Java.
¿Qué es la Herencia?
El concepto de herencia en programación es muy semejante al concepto de herencia en biología. Es por ello que comienzo a explicar este concepto partiendo de la definición de esta palabra, según el Diccionario de la Lengua Española:
Es un Conjunto de caracteres que los seres vivos reciben de sus progenitores.
En Programación:
La herencia es un mecanismo que permite la definición de una clase a partir de otra ya existente, lo que permite compartir automáticamente métodos y datos entre clases, subclases y objetos. (link)
Por lo tanto, la clase de la cual se deriva otra clase se denomina clase padre o superclase. Mientras que a una clase derivada de una superclase se denomina subclase o clase hija. Esto lo puedes apreciar en la figura 1.

Figura 1. Superclase y subclases.
La clase hija tiene todo lo que la clase padre tiene, es decir, las propiedades y métodos de la clase padre. Sin embargo, en la clase hija se definen las diferencias con la clase padre, agregando atributos y métodos que no existen en la clase padre.
Al igual que la herencia entre seres vivos, la herencia en programación nos ayuda a:
- Extender la funcionalidad de la clase padre. Es decir, podemos aprovechar el código escrito en la clase padre más veces, pues lo podremos utilizar en los objetos de las subclases.
- Especializar el comportamiento de la clase padre. Además de usar los métodos originales de la clase padre, estos pueden ser mejorados, es decir especializados.
- Finalmente, esto nos lleva a la reutilización de código.
El tema de herencia en la POO es sumamente importante, porque es uno de los principios de éste paradigma de programación, por lo que te recomiendo leer el sitio de Guru 99, que contiene una descripción concisa de una serie de conceptos relacionados con la herencia.
Jerarquía de clases.
Conforme creamos relaciones de herencia entre clases y subclase, como resultado obtendremos una estructura jerárquica en forma de árbol invertido. Esta estructura se conoce con el nombre técnico de jerarquía de clases o jerarquía de herencia. Un ejemplo de esta jerarquía se muestra en la figura 2.

Figura 2. Ejemplo de jerarquía de clases.
En este ejemplo, la superclase es “Animal”, y sus clases hijas son “Carnívoro”, “Herbívoro” y “Omnívoro”. Y a su vez, estas clases hijas son superclases de sus descendientes. Específicamente, “Herbívoro” es superclase de “Rumiante” e “Insecto”, quien a su vez es superclase de “Termita” y “Oruga”.
Esta jerarquía de clases representa una relación entre los objetos del tipo “es un”. Por ejemplo, un Lobo es un Cánido, que a su vez es un Carnívoro. Esta relación es importante porque nos recuerda que, si bien un Lobo es un animal muy diferente a un Coyote, tiene características similares a este al ser ambos Cánidos y a su vez Carnívoros.
En programación, esto implica que las clases hijas conservarán los atributos y métodos de la clase padre. Y en el universo de clases de java, la superclase de cualquier clase que se escriba es Object.
¿Cómo crear una superclase?
Al construir una superclase en primer lugar debes pensar en los atributos y métodos generales que posee este nivel de abstracción. A este proceso se le denomina generalización, y está ilustrado en la figura 3.

Figura 3. Proceso de generalización al construir una superclase
En el ejemplo mostrado iniciamos con una superclase denominada “Persona”, del cual descienden las subclases “Estudiante” y “Docente”. Por lo que, para encontrar qué propiedades y métodos deben pertenecer a la superclase, tenemos que preguntarnos:
- ¿Cuáles son los atributos comunes a todas las personas, sin importar si son estudiantes o docentes?
- ¿Cuáles son las acciones comunes que todas las personas realizan?
Es decir, buscamos atributos generales, que estarán presentes en todas las subclases. Por lo tanto, el proceso de generalización es simple y obvio, pues aprovecha las bondades del paradigma de la Programación Orientada a Objetos.
Como resultado del proceso de generalización, detecto que los atributos: nombre, apellido paterno, apellido materno, edad y domicilio son las características comunes a cualquier persona, sin importar si es un estudiante o un maestro. A continuación muestro el código de la superclase:
public class Persona { private String nombre; private String apellidoPaterno; private String apellidoMaterno; private int edad; private String domicilio; public Persona(String nomb, String apellido1, String apellido2){ this.nombre = nomb; this.apellidoPaterno = apellido1; this.apellidoMaterno = apellido2; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidoPaterno() { return apellidoPaterno; } public void setApellidoPaterno(String apellidoPaterno) { this.apellidoPaterno = apellidoPaterno; } public String getApellidoMaterno() { return apellidoMaterno; } public void setApellidoMaterno(String apellidoMaterno) { this.apellidoMaterno = apellidoMaterno; } public int getEdad() { return edad; } public void setEdad(int edad) { this.edad = edad; } public String getDomicilio() { return domicilio; } public void setDomicilio(String domicilio) { this.domicilio= domicilio; } @Override public String toString() { return "Persona{" + "nombre=" + nombre + ", apellidoPaterno=" + apellidoPaterno + ", apellidoMaterno=" + apellidoMaterno + ", edad=" + edad + ", domicilio=" + domicilio+ '}'; } }
¿Cómo crear una subclase?
Al construir una subclase, en primer lugar debes pensar en los atributos y métodos únicos para esta clase, que la hacen ser diferentes a la clase padre. A este proceso se le denomina especialización, y lo puedes observar en la figura 4.

Figura 4. El proceso de especialización al construir una subclase.
Ahora para encontrar qué propiedades y métodos deben pertenecer a cada subclase, tenemos que preguntarnos:
- ¿Cuáles son los atributos específicos de los estudiantes que no pueden ser atributos de los docentes?
- ¿Cuáles son las acciones comunes que todos los estudiantes realizan, que no pueden realizar los docentes?
Construyendo una subclase.
Para crear una clase hija, se utiliza la palabra: extends y el nombre de la superclase de la cual hereda, como puedes observar en la figura 5.

Figura 5. Creación de una subclase
El constructor de la clase hija.
Cuando se construye una subclase, esta se vuelve dependiente de la superclase, por lo que la primer línea de su constructor debe ser una llamada al constructor de la superclase. Esto se logra con la palabra clave super.

Figura 6. El constructor de la subclase.
Como puedes ver en la figura 6, en el constructor de la clase hija, lo primero que hacemos es la llamada al constructor de la clase padre, usando super. Después procedemos a inicializar los atributos de la clase estudiante, en este caso, únicamente la matrícula. Ten en cuenta que olvidar el llamado al constructor de la super clase o incluso invertir el orden de las instrucciones, te arrojará un error de sintaxis.
De esta forma, el código de la subclase queda como te muestro a continuación:
public class Estudiante extends Persona{ private String matricula; private double promedio; private int grado; private char grupo; private String carrera; public Estudiante(String n, String a1, String a2, String m){ super(n, a1, a2); this.matricula = m; } public String getCarrera() { return carrera; } public void setCarrera(String carrera) { this.carrera = carrera; } public String getMatricula() { return matricula; } public void setMatricula(String matricula) { this.matricula = matricula; } public double getPromedio() { return promedio; } public void setPromedio(double promedio) { this.promedio = promedio; } public void setPromedio(double p1, double p2, double p3, double p4){ this.promedio = (p1 + p2 + p3 + p4)/4; } public int getGrado() { return grado; } public void setGrado(int grado) { this.grado = grado; } public char getGrupo() { return grupo; } public void setGrupo(char grupo) { this.grupo = grupo; } @Override public String toString() { String cad1 = super.toString(); String cad2 = "Estudiante{" + "matricula=" + matricula + ", promedio=" + promedio + ", grado=" + grado + ", grupo=" + grupo + ",carrera=" + carrera + '}'; return cad1 + " " + cad2; } }
Acceso a los métodos de la clase padre desde la clase hija.
La clase hija puede acceder a los métodos de la clase padre, ya que los hereda. Por lo tanto, sólo es necesario utilizar la palabra reservada super cada vez que se necesite hacer una referencia a un método perteneciente a la clase padre.
Ahora observa nuevamente el código de la clase Estudiante, específicamente el método toString(). En la primera línea de éste método, estamos invocando al toString() de la superclase (es decir de Persona), de la siguiente forma:
String cad1 = super.toString();
El ejemplo anterior muestra a la variable cad1 recibiendo la cadena que regresa el método toString() de Persona. Para asegurarnos de llamar al método de la super clase, como ya se ha dicho, usamos la palabra super, seguida del operador punto, y del nombre del método que necesitamos invocar.
Esto es importante porque si ambas clases tienen definidos un método con el mismo nombre – como en este caso, con el método toString() – usaremos super para invocar al método de la superclase y no el de la clase hija.
Declaración y uso de objetos de superclase y subclase.
Una vez que hemos creado las clases, podemos crear objetos y utilizarlos en un programa:
public class ProyectoHerencia { public static void main(String[] args) throws IOException { // Declaración de objetos Persona unaPersona; Estudiante unEstudiante; // Construccion de unaPersona unaPersona = new Persona("Pánfilo", "López", "Sánchez"); unaPersona.setDireccion("Avenida Siempre Viva # 234"); unaPersona.setEdad(22); System.out.println(unaPersona.toString()); // Muestra todos los datos de unaPersona // Construcción de un Estudiante unEstudiante = new Estudiante("Tiburcio", "Macías", "Aguayo", "ICC-2017-001"); unEstudiante.setPromedio(10, 8, 8, 9); unEstudiante.setCarrera("Ciencias de la Computación"); unEstudiante.setGrupo('A'); unEstudiante.setGrado(1); unEstudiante.setEdad(18); unEstudiante.setDomicilio("Baranca del Muerto # 249"); System.out.println(unEstudiante.toString()); // Muestra todos los datos de unEstudiante } }
Como puedes observar en el listado anterior, la creación del objeto unaPersona no tiene nada de diferente a la creación de un objeto cualquiera. Lo interesante sucede en la creación del objeto unEstudiante, como se enlista a continuación:
- El llamado al constructor debe incluir los argumentos que se requieren en la superclase, en este caso: nombre, apellido paterno y apellido materno, más el argumento matrícula, propio de la clase Estudiante. Puesto que se trata de una clase hija, no debemos olvidar los argumentos del constructor de la clase padre.
- Los métodos setPromedio, setCarrera, setGrupo y setGrado, son propios de la clase Estudiante y la forma de invocarlos no es nada diferente a la invocación de cualquier método perteneciente a una clase.
- Los métodos setEdad y setDomicilio son métodos de la clase Persona, que Estudiante hereda. Sin embargo, observa como a través del mecanismo de herencia, el objeto unEstudiante puede invocarlos como si fueran sus propios métodos.
Éste último punto representa la ventaja de usar la herencia: se escriben los métodos para una clase, y la clase descendiente tiene derecho a utilizarlos.
Difunde el conocimiento.
Esta fue mi aportación sobre la herencia en Java. Ten en cuenta que aún hay mucho que decir sobre este tema, pero lo importante es que con este material puedes comenzar a crear tus propias jerarquías de clases. Finalmente, observa que el ejercicio aún no está completo, ya que la clase “Docente” no se escribió. ¿Te animas a crearla?
Cuéntame como te va con esto, y si tienes alguna duda, deja tu comentario para apoyarte.
No olvides compartir este artículo en tus redes sociales. ¡Hasta la próxima!
Buenas noches miss Gaby, me gustó mucho la explicación de la herencia de Java, me está quedando muy claro, cada vez voy avanzando más.
Gracias porque es de mucha ayuda su blog. <3
Es posible que una subclase tenga dos clases base, por ejemplo, hij@ como subclase y como superclases existan las clases madre y padre.
Es posible en otros lenguajes de programación orientados a objetos pero no en Java
No, la herencia múltiple no está soportada en Java
una pregunta cuantas subclases pueden heredar de una misma super clase, existe un limite de subclases el cual no podemos superar??
No existe límite
¿Cuántos tipos de herencia hay en Java’?
En la POO existen dos tipos de herencia: múltiple y simple. El lenguaje Java sólo soporta la herencia simple
leido…
leido
La herencia es uno de los cuatro pilares de la Programación Orientada a Objetos.
Es un mecanismo que permite la definición de una clase a partir de otra ya existente, lo que permite compartir automáticamente métodos y datos entre clases, subclases y objetos.
La clase de la cual se deriva otra clase se denomina clase padre o superclase.
La clase derivada de una superclase se denomina subclase o clase hija.
Cuando se construye una subclase, esta se vuelve dependiente de la superclase.
Conforme se crea las relaciones de herencia entre clase y subclase como resultado se obtiene la jerarquía de clases o jerarquía de herencia.
leído
porque solamente en lenguaje java soporta la herencia simple?
Los creadores del lenguaje Java tenían experiencia en programación con C++, el cual también es un lenguaje orientado a objetos. C++ sí soporta herencia múltiple, pero los creadores de Java consideraron que generaba más problemas para los programadores que beneficios. Por eso fue incluida una solución alterna a través del uso de las interfaces
cuando vamos a crear el constructor, tenemos que crear la palabra super pero mi duda aqui es que vamos a las variables de la clase retomo el ejemplo de hija y padre, declaro super y tengo que poner en los paréntesis las variables de la clase padre o de la subclase?
Hola, en super() Los argumentos que debes enviar son los que necesite el constructor de la clase padre
Aun no me queda claro cuando creamos el constructor con la palabra clave super en los parentesís tenemos que poner los datos de la clase padre o de la clase hija?
y tambien sobre el this tengo que poner el atributo de la clase padre o hija?
Hola! Recuerda que al usar super() haces un llamado al método constructor de la clase padre, por lo que debes enviar los argumentos que necesite el constructor de la super clase. En cuanto a this, se refiere al objeto de la clase hija, ahí deberás inicializar las propiedades de la clase hija
Tengo duda de cual es lo maximo de subclases q puede haber en una superclase
También todavia no me queda claro como se utiliza el extends
Con la palabra extends estas indicando que la clase que estas creando extiende de otra clase. Es decir, usas esa palabra para crear una subclase. Y se pueden crear tantas subclases como sean necesarias
Cuantas subclases pude haber en una super clase?
Tambien todavia no me queda claro como se usa el extends