La herencia es uno de los pilares de la programación orientada a objetos. Permite que una clase adquiera las propiedades y comportamientos de otra, promoviendo la reutilización del código y una estructura más clara.
1. ¿Qué es la herencia?
La herencia permite que una clase (llamada subclase) herede atributos y métodos de otra clase (llamada superclase). Esto crea una relación «es un» entre las clases.
Sintaxis básica:
class Subclase extends Superclase {
// Nuevos atributos y métodos de la subclase
}
Ejemplo básico:
public class Animal {
public void comer() {
System.out.println("Este animal está comiendo.");
}
}
public class Perro extends Animal {
public void ladrar() {
System.out.println("El perro está ladrando.");
}
}
public class Principal {
public static void main(String[] args) {
Perro miPerro = new Perro();
miPerro.comer(); // Método heredado
miPerro.ladrar(); // Método de la subclase
}
}
Salida:
Este animal está comiendo. El perro está ladrando.
2. Características clave de la herencia
- Reutilización del código:
- Las subclases pueden usar atributos y métodos definidos en la superclase.
- Especialización:
- Las subclases pueden agregar atributos y métodos adicionales para ampliar o modificar el comportamiento de la superclase.
- Relación jerárquica:
- Java no permite herencia múltiple directa (una clase no puede extender más de una clase).
Ejemplo de jerarquía:
public class Animal {
public void hacerSonido() {
System.out.println("El animal hace un sonido.");
}
}
public class Gato extends Animal {
@Override
public void hacerSonido() {
System.out.println("El gato maúlla.");
}
}
3. Uso de super
La palabra clave super se utiliza para:
Llamar al constructor de la superclase:
public class Animal {
public Animal(String nombre) {
System.out.println("Animal: " + nombre);
}
}
public class Perro extends Animal {
public Perro(String nombre) {
super(nombre); // Llama al constructor de la superclase
System.out.println("Perro: " + nombre);
}
}
Salida:
Animal: Max Perro: Max
Acceder a métodos o atributos de la superclase:
public class Animal {
public void dormir() {
System.out.println("El animal está durmiendo.");
}
}
public class Perro extends Animal {
public void dormir() {
super.dormir(); // Llama al método de la superclase
System.out.println("El perro está roncando.");
}
}
Salida:
El animal está durmiendo. El perro está roncando.
4. Modificadores de acceso y herencia
| Modificador | Accesible en subclases del mismo paquete | Accesible en subclases de otros paquetes |
|---|---|---|
public | Sí | Sí |
protected | Sí | Sí |
| Sin modificador | Sí | No |
private | No | No |
5. Sobreescritura de métodos (@Override)
La sobreescritura permite que una subclase redefina el comportamiento de un método heredado.
Reglas de sobreescritura:
- El método debe tener el mismo nombre, tipo de retorno y parámetros.
- El método no puede tener un modificador más restrictivo.
- Se recomienda usar la anotación
@Override.
Ejemplo:
public class Animal {
public void hacerSonido() {
System.out.println("El animal hace un sonido.");
}
}
public class Gato extends Animal {
@Override
public void hacerSonido() {
System.out.println("El gato maúlla.");
}
}
public class Principal {
public static void main(String[] args) {
Animal miAnimal = new Gato();
miAnimal.hacerSonido(); // Llama al método de la subclase
}
}
Salida:
El gato maúlla.
6. Clases finales y abstractas
Clases finales (final):
public final class Animal {
// Esta clase no puede tener subclases
}
Clases abstractas:
public abstract class Animal {
public abstract void hacerSonido();
}
public class Perro extends Animal {
@Override
public void hacerSonido() {
System.out.println("El perro ladra.");
}
}
7. Errores comunes con la herencia
- Acceso restringido a métodos heredados:
- Si un método heredado es
private, no está disponible en la subclase.
- Si un método heredado es
- Dependencia circular:
- Java no permite que dos clases se extiendan mutuamente.
- Herencia innecesaria:
- Usa herencia solo si existe una clara relación «es un».
Resumen
- La herencia permite reutilizar código y crear jerarquías de clases.
- Usa
superpara acceder a constructores y métodos de la superclase. - La sobreescritura (
@Override) redefine comportamientos en las subclases. - Entiende las diferencias entre clases finales y abstractas para aplicarlas correctamente.