¡Hola! Ya estás usando métodos Java y sabes mucho sobre ellos. Probablemente te hayas enfrentado a la situación en la que una clase tiene muchos métodos con el mismo nombre pero diferentes parámetros. Recordarás que en esos casos usamos sobrecarga de métodos. Hoy estamos considerando otra situación. Imagine que tenemos un solo método compartido, pero debe hacer cosas diferentes en diferentes clases. ¿Cómo implementamos este comportamiento? Para entenderlo, consideremos una clase padre Animal , que representa animales, y crearemos un método de habla en ella:
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Aunque recién comenzamos a escribir el programa, probablemente vea un problema potencial: hay muchos animales en el mundo, y todos 'hablan' de manera diferente: los gatos maúllan, los patos graznan y las serpientes silban. Nuestro objetivo es simple: evitar crear muchos métodos de habla. En lugar de crear un método catSpeak() para maullar, un método snakeSpeak() para silbar, etc., queremos llamar al método speak()método y haz que la serpiente silbe, el gato maúlle y el perro ladre. Podemos lograr esto fácilmente usando la anulación de métodos. Wikipedia da la siguiente explicación del término 'anulación': La anulación de métodos, en la programación orientada a objetos, es una característica del lenguaje que permite que una subclase o clase secundaria proporcione una implementación específica de un método que ya proporciona una de sus superclases o clases de padres Eso es esencialmente correcto. La anulación de métodos le permite tomar algún método de la clase principal y escribir su propia implementación en cada clase secundaria. La nueva implementación 'reemplaza' la implementación del padre en la clase secundaria. Veamos cómo se ve esto en un ejemplo. Crea 4 clases que heredan nuestra clase Animal :
public class Bear extends Animal {
@Override
public void speak() {
System.out.println("Growl!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void speak() {
System.out.println("Hiss!");
}
}
"Aquí hay un pequeño truco para el futuro: para anular los métodos de la clase principal, vaya al código de la clase secundaria en el IDE de IntelliJ, haga clic en Ctrl+O y seleccione "Anular métodos..." en el menú. Acostúmbrese a usar las teclas de acceso rápido desde el principio, ¡lo ayudará a escribir programas más rápido! Para especificar el comportamiento que necesitamos, hicimos algunas cosas:
- En cada clase secundaria, creamos un método con el mismo nombre que el método de la clase principal.
- Le dijimos al compilador que nombrar el método de la misma manera que en la clase principal no fue una casualidad: queremos anular su comportamiento. Para comunicar esto al compilador, configuramos la anotación @Override sobre el método.
Cuando se coloca sobre un método, la anotación @Override informa al compilador (así como a los programadores que leen su código): 'Todo está bien. Esto no es un error. No estoy siendo olvidadizo. Soy consciente de que ese método ya existe y quiero anularlo'. - Escribimos la implementación que necesitamos para cada clase secundaria. Cuando se llama al método speak() , una serpiente debe silbar, un oso debe gruñir, etc.
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Bear();
Animal animal4 = new Snake();
animal1.speak();
animal2.speak();
animal3.speak();
animal4.speak();
}
}
Salida de la consola:
Woof!
Meow!
Growl!
Hiss!
¡Excelente! ¡Todo funciona como deberia! Creamos 4 variables de referencia que almacenan objetos de la clase principal Animal y les asignamos instancias de 4 clases secundarias diferentes. Como resultado, cada objeto exhibe su propio comportamiento. Para cada clase secundaria, el método speak() anulado reemplazó al método speak() 'nativo' en la clase Animal (que simplemente muestra '¡Hola!'). La anulación tiene varias limitaciones:
-
El método anulado debe tener los mismos parámetros que el método principal.
Si el método de habla de la clase principal tiene un parámetro de cadena , el método anulado en la clase secundaria también debe tener un parámetro de cadena . De lo contrario, el compilador generará un error:
public class Animal { public void speak(String s) { System.out.println("Hello! " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
El método anulado debe tener el mismo tipo de valor devuelto que el método principal.
De lo contrario, obtendremos un error de compilación:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override public String speak() { // Error! System.out.println("Meow!"); return "Meow!"; } }
-
El modificador de acceso en el método anulado también debe ser el mismo que el método 'original':
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override private void speak() { // Error! System.out.println("Meow!"); } }
GO TO FULL VERSION