
Animal
clase principal, que representa a los animales, y creemos un
speak
método en ella:
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Aunque recién comenzamos a escribir nuestro programa, probablemente pueda ver un problema potencial: el mundo está lleno de muchos animales, y todos "hablan" de manera diferente: los gatos maúllan, los patos graznan, las serpientes silban, etc. Nuestro objetivo es simple:

meow()
método para maullar,
hiss()
silbar, etc., queremos que la serpiente silbe, el gato maúlle y el perro ladre cuando
speak()
se llame al método. Podemos lograr esto fácilmente usando
la anulación del método . Wikipedia explica el término de la siguiente manera:
Anulación de método, 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 principales. Eso es básicamente correcto. La anulación le permite tomar algún método de una clase principal y escribir su propia implementación en cada clase derivada. La nueva implementación en la clase secundaria "reemplaza" a la principal. Veamos cómo se ve esto con un ejemplo. Vamos a crear 4 descendientes de nuestra
Animal
clase:
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 una clase principal, acceda al código de la clase derivada en
IntelliJ IDE , presione
Ctrl+O y seleccione
Anular métodos... en el menú. Acostúmbrate a usar teclas de acceso rápido desde el principio. ¡Acelerarán la codificación! Para obtener el comportamiento deseado, hicimos algunas cosas:
- En cada clase descendiente, creamos un método con el mismo nombre que el método de la clase principal.
-
Le dijimos al compilador que no solo le estamos dando al método el mismo nombre que en la clase principal, sino que queremos anular su comportamiento. Este "mensaje" al compilador se transmite a través de la anotación @Override .
La anotación @Override encima de un método le dice al compilador (así como a otros programadores que leen su código), "No se preocupe. Esto no es un error ni un descuido. Soy consciente de que este método ya existe y quiero anularlo". . - Escribimos la implementación que necesitamos para cada clase descendiente. Cuando
speak()
se llama al método, una serpiente debe silbar, un oso debe gruñir, y así sucesivamente.
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!
¡Genial, todo funciona como debería! Creamos 4 variables de referencia cuyo tipo es la
Animal
clase padre y les asignamos 4 objetos diferentes de las clases descendientes. Como resultado, cada objeto se comporta de manera diferente. Para cada una de las clases derivadas, el
speak()
método anulado reemplaza el método existente
speak()
de la
Animal
clase (que simplemente muestra "Hablando:" en la consola).

-
Un método anulado debe tener los mismos argumentos que el método de la clase principal.
Si el
speak
método de la clase padre toma aString
como entrada, entonces el método invalidado en la clase descendiente también debe tomar aString
como entrada. De lo contrario, el compilador generará un error:public class Animal { public void speak(String s) { System.out.println("Speaking: " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
El método invalidado debe tener el mismo tipo de valor devuelto que el método de la clase 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 del método anulado tampoco puede diferir del 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!"); } }
speak()
método único para todos en lugar de un montón de métodos diferentes, por ejemplo
bark()
,
meow()
, etc.
GO TO FULL VERSION