Sobreescritura
En Java, el overriding se refiere a la capacidad de una subclase para redefinir (sobrescribir) un método de su superclase. Esto significa que una subclase puede proporcionar una implementación diferente de un método que ya existe en su superclase. El objetivo principal de esto es permitir a las subclases personalizar el comportamiento heredado.
Para sobrescribir un método, la subclase debe tener la misma firma (nombre del método, tipo de retorno y argumentos) que el método de la superclase. Además, la anotación @Override debe utilizarse para indicar que el método está siendo sobrescrito.
Aquí hay un ejemplo de cómo se usa el overriding en Java:
class Animal {
public void move() {
System.out.println("Los animales se mueven de diferentes maneras.");
}
}
class Dog extends Animal {
@Override
public void move() {
System.out.println("Los perros corren y caminan.");
}
}
class Fish extends Animal {
@Override
public void move() {
System.out.println("Los peces nadan.");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Animal();
a.move(); // Imprime "Los animales se mueven de diferentes maneras."
Animal d = new Dog();
d.move(); // Imprime "Los perros corren y caminan."
Animal f = new Fish();
f.move(); // Imprime "Los peces nadan."
}
}
En este ejemplo, la clase Animal tiene un método move() que se sobrescribe en las subclases Dog y Fish. Cada subclase proporciona su propia implementación de move() para personalizar el comportamiento heredado.
En Java, se recomienda usar la etiqueta @Override cuando se sobreescribe un método. Esto ayuda a evitar errores como sobreescribir un método que no existe o tiene una firma de método diferente. Además, la etiqueta @Override también ayuda a mejorar la legibilidad del código ya que indica intencionalmente que un método es una sobreescritura. Sin embargo, no es obligatorio usar la etiqueta @Override y el código todavía funcionará correctamente si no se utiliza.
Supongamos que estás desarrollando un sistema para una institución educativa que tiene diferentes tipos de cursos. Existe una clase base llamada Curso
que contiene información común a todos los cursos, como el nombre del curso, el número de créditos, y el costo. Luego, tienes clases derivadas para cursos específicos, como CursoMatematicas
, CursoHistoria
, y CursoInformatica
, que heredan de la clase base Curso
.
En este escenario, el método calcularCosto()
en la clase base Curso
puede ser anulado (overridden) en las clases derivadas para proporcionar un cálculo de costo específico para cada tipo de curso. Aquí tienes un ejemplo simplificado:
class Curso {
private String nombre;
private int creditos;
private double costo;
public Curso(String nombre, int creditos, double costo) {
this.nombre = nombre;
this.creditos = creditos;
this.costo = costo;
}
public double calcularCosto() {
// Cálculo de costo genérico
return creditos * costo;
}
public void mostrarDetalles() {
System.out.println("Nombre: " + nombre);
System.out.println("Créditos: " + creditos);
System.out.println("Costo: $" + costo);
}
}
class CursoMatematicas extends Curso {
public CursoMatematicas(String nombre, int creditos, double costo) {
super(nombre, creditos, costo);
}
@Override
public double calcularCosto() {
// Cálculo de costo específico para cursos de matemáticas
return super.calcularCosto() * 1.2; // Se aplica un 20% de recargo
}
}
class CursoHistoria extends Curso {
public CursoHistoria(String nombre, int creditos, double costo) {
super(nombre, creditos, costo);
}
@Override
public double calcularCosto() {
// Cálculo de costo específico para cursos de historia
return super.calcularCosto() * 1.1; // Se aplica un 10% de recargo
}
}
En este ejemplo, la clase base Curso
tiene un método calcularCosto()
que puede ser anulado en las clases derivadas. Las clases CursoMatematicas
y CursoHistoria
anulan el método calcularCosto()
para proporcionar cálculos de costo específicos para cursos de matemáticas e historia, respectivamente. El uso del método super.calcularCosto()
permite llamar al método de la clase base antes de aplicar el recargo específico de cada tipo de curso.
El overriding en la herencia permite que cada tipo de curso tenga su propia implementación personalizada del cálculo de costo, manteniendo la estructura de herencia.