Cuando una subclase proporciona una implementación específica para un método que ya está definido en su clase principal, se denomina anulación de método. El método anulado en la subclase debe tener los mismos parámetros de nombre y tipo de retorno que el método de la clase principal.
Reglas para anular métodos
- Los parámetros de nombre y el tipo de retorno deben coincidir con el método principal.
- Java elige qué método ejecutar en tiempo de ejecución en función del tipo de objeto real, no solo del tipo de variable de referencia.
- Los métodos estáticos no se pueden anular.
- El @Anular anotación detecta errores como errores tipográficos en los nombres de los métodos.
class Animal { void move(){ System.out.println( 'Animal is moving.'); } void eat(){ System.out.println( 'Animal is eating.'); } } class Dog extends Animal{ @Override void move(){ // move method from Base class is overriden in this // method System.out.println('Dog is running.'); } void bark(){ System.out.println('Dog is barking.'); } } public class Geeks { public static void main(String[] args) { Dog d = new Dog(); d.move(); d.eat(); d.bark(); } }
Producción
Dog is running. Animal is eating. Dog is barking.
Explicación: La clase Animal define funcionalidades básicas como mover() y comer() . La clase Perro hereda de Animal y anula el método move() para proporcionar un comportamiento específico El perro corre. Ambas clases pueden acceder a sus propios métodos. Al crear un objeto Perro, llamar a move() ejecuta el método anulado.
np donde

Casos especiales en anulación
1. Llamar al método principal usando super
El súper palabra clave Puede invocar el método de la clase principal desde el método principal.
Javaclass Parent{ void show(){ System.out.println('Parent's show()'); } } class Child extends Parent{ @Override void show(){ super.show(); System.out.println('Child's show()'); } } public class Main{ public static void main(String[] args){ Parent obj = new Child(); obj.show(); } }
Producción
Parent's show() Child's show()
2. Los métodos finales no se pueden anular
Si no queremos que se anule un método, lo declaramos como final . por favor vea Usando Final con herencia .
Javaclass Parent{ // Can't be overridden final void show(){ } } class Child extends Parent{ // This would produce error void show() {} }
Producción :
3. Métodos estáticos
- Los métodos estáticos no se pueden anular; definir un método estático en una subclase con la misma firma que en la superclase oculta el método de la superclase.
- Los métodos de instancia se pueden anular, pero una subclase no puede anular un método estático de superclase.
- Un método estático en una subclase con la misma firma que un método estático de superclase oculta el método original.
class Parent{ static void staticMethod(){ System.out.println('Parent static method'); } void instanceMethod(){ System.out.println('Parent instance method'); } } class Child extends Parent{ static void staticMethod(){ // Hides Parent's static method System.out.println('Child static method'); } @Override void instanceMethod(){ // Overrides Parent's instance method System.out.println('Child instance method'); } } public class GFG{ public static void main(String[] args){ Parent p = new Child(); // Calls Parent's static method (hiding) p.staticMethod(); // Calls Child's overridden instance method p.instanceMethod(); } }
Producción
Parent static method Child instance method
4. Métodos privados
- Los métodos privados no se pueden anular porque no son visibles para las subclases.
- Un método de subclase con el mismo nombre se trata como un nuevo método independiente no relacionado con la clase principal.
class Parent{ private void display(){ System.out.println('Parent private method'); } } class Child extends Parent{ void display(){ // This is a new method not overriding System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ Child c = new Child(); // Calls Child's method c.display(); } }
Producción
Child method
5. Tipos de retorno covariantes
- En la anulación de métodos, el tipo de retorno del método anulado puede ser una subclase del tipo de retorno del método anulado.
- Esta característica se conoce como tipo de retorno covariante y permite tipos de retorno más específicos en la subclase.
class Parent{ Parent getObject(){ System.out.println('Parent object'); return new Parent(); } } class Child extends Parent{ @Override // Covariant return type Child getObject() { System.out.println('Child object'); return new Child(); } } public class GFG{ public static void main(String[] args){ Parent obj = new Child(); // Calls Child's method obj.getObject(); } }
Producción
Child object
Manejo de excepciones en anulación
- El método predominante no puede generar excepciones comprobadas nuevas o más amplias que el método de la superclase.
- Puede generar menos excepciones marcadas o más limitadas.
- Puede generar excepciones no comprobadas (como RuntimeException) independientemente del método de superclase.
import java.io.IOException; class Parent { void display() throws IOException { System.out.println('Parent method'); } } class Child extends Parent { @Override void display() throws IOException { System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ // Parent reference Child object Parent obj = new Child(); try{ // Calls Child's overridden method obj.display(); } catch (IOException e){ System.out.println('Exception caught: ' + e.getMessage()); } } }
Producción
Child method
¿Por qué utilizamos la anulación de métodos?
- Cambiar o mejorar el comportamiento de un método existente en una subclase.
- Para lograr polimorfismo en tiempo de ejecución, las llamadas a métodos dependen del tipo de objeto real.
- Reutilizar nombres de métodos reduciendo lógicamente la redundancia.
Ejemplo de la vida real: sistema de gestión de empleados
Entendamos la anulación con una analogía del mundo real.
Imagine el sistema de gestión de empleados de una organización. Todos los empleados comparten algunos comportamientos como aumentarSalario() y promover() pero la lógica difiere para diferentes roles como Gerente o Ingeniero. Podemos crear una única matriz de empleados donde los empleados individuales sean de diferentes tipos (técnicos de ventas, etc.) y llamar a sus funciones. Esto simplifica mucho el código general.
Javaabstract class Employee { abstract void raiseSalary(); abstract void promote(); } class Manager extends Employee{ @Override void raiseSalary(){ System.out.println( 'Manager salary raised with incentives.'); } @Override void promote(){ System.out.println( 'Manager promoted to Senior Manager.'); } } class Engineer extends Employee{ @Override void raiseSalary(){ System.out.println( 'Engineer salary raised with bonus.'); } @Override void promote(){ System.out.println( 'Engineer promoted to Senior Engineer.'); } } public class Company{ public static void main(String[] args){ Employee[] employees = { new Manager() new Engineer() }; System.out.println('--- Raising Salaries ---'); for (Employee e : employees){ e.raiseSalary(); } System.out.println('n--- Promotions ---'); for (Employee e : employees) { e.promote(); } } }
Producción
--- Raising Salaries --- Manager salary raised with incentives. Engineer salary raised with bonus. --- Promotions --- Manager promoted to Senior Manager. Engineer promoted to Senior Engineer.
Explicación: Aunque se hace referencia a los objetos Manager e Engineer utilizando el tipo Empleado, Java llama a los métodos anulados de los objetos reales en tiempo de ejecución, lo que demuestra el envío de métodos dinámicos (polimorfismo en tiempo de ejecución).
lista doblemente enlazada
Artículo relacionado: Sobrecarga de métodos y anulación de métodos