Animal
denoting animals and create a method in it voice
- “ voice ”:
public class Animal {
public void voice() {
System.out.println("Voice!");
}
}
Although we have just started writing the program, you can most likely see the potential problem: there are a lot of animals in the world, and they all “speak” differently: cats meow, ducks quack, snakes hiss. Our goal is simple: avoid creating a bunch of methods for casting a vote. Instead of creating methods voiceCat()
for meowing, voiceSnake()
for hissing, etc., we want voice()
the snake to hiss, the cat to meow, and the dog to bark when the method is called. We can easily achieve this using the method overriding mechanism (Override in Java) . Wikipedia gives the following explanation of the term “overriding”: Method overriding in object - oriented programming is one of the features of a programming language that allows a subclass or child class to provide a specific implementation of a method already implemented in one of the superclasses or parent classes. It is, in general, correct. Overriding allows you to take a method of a parent class and write your own implementation of this method in each descendant class. The new implementation will "replace" the parent in the child class. Let's see what this looks like with an example. Let's create 4 successor classes for our class Animal
:
public class Bear extends Animal {
@Override
public void voice() {
System.out.println("Р-р-р!");
}
}
public class Cat extends Animal {
@Override
public void voice() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void voice() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void voice() {
System.out.println("Ш-ш-ш!");
}
}
A small life hack for the future: to override the methods of the parent class, go to the code of the descendant class in Intellij IDE a, press Ctrl+O and select “ Override methods... ” from the menu. Get used to using hotkeys from the beginning, it will speed up writing programs! To set the behavior we wanted, we did a few things:
- We created a method in each descendant class with the same name as the method in the parent class.
-
We told the compiler that we named the method the same as in the parent class for a reason: we wanted to override its behavior. For this “message” to the compiler, we put an @Override annotation on the method .
The @Override annotation placed above a method tells the compiler (and programmers reading your code too): “Everything is ok, this is not a mistake or my forgetfulness. I remember that such a method already exists, and I want to override it." - We wrote the implementation we needed for each descendant class. When called, a snake
voice()
should hiss, a bear should growl, 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.voice();
animal2.voice();
animal3.voice();
animal4.voice();
}
}
Console output: Woof! Meow! Rrrr! Shhh! Great, everything works as it should! We created 4 reference variables of the parent class Animal
, and assigned them to 4 different objects of the descendant classes. As a result, each object behaves differently. For each of the descendant classes, the overridden method voice()
replaced the “native” method voice()
from the class Animal
(which simply outputs “Voice!” to the console). Overriding has a number of limitations:
-
The overridden method must have the same arguments as the parent method.
If a method
voice
in a parent class accepts as inputString
, the overridden method in the child class must also accept as inputString
, otherwise the compiler will throw an error:public class Animal { public void voice(String s) { System.out.println("Voice! " + s); } } public class Cat extends Animal { @Override//error! public void voice() { System.out.println("Meow!"); } }
-
The overridden method must have the same return type as the parent method.
Otherwise, we will receive a compilation error:
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override public String voice() { //error! System.out.println("Meow!"); return "Meow!"; } }
-
The access modifier of an overridden method also cannot differ from the “original” one:
public class Animal { public void voice() { System.out.println("Voice!"); } } public class Cat extends Animal { @Override private void voice() { //error! System.out.println("Meow!"); } }
voice()
for all instead of a bunch of methods voiceDog()
, voiceCat()
etc.
GO TO FULL VERSION