Overriding a static method in Java
You can't override static methods in Java. But why does the following code work:
public class Runner {
public static void main(String[] args) {
B.fun();
}
}
class A {
public static void fun() {
System.out.println("A");
}
}
class B extends A {
public static void fun() {
System.out.println("B");
}
}
"B"is printed. It looks like it's an override. Because when overloading, I would have to change something in the method signature. But no, I didn't change anything.
I can't put the "override" annotation above the method.
2 answers
Let's start in order
Redefining a method:
Redefining a method (Method overriding) is a language feature that allows a subclass or child of a class to provide a specific implementation of a method that has already been implemented in one of the superclasses or the parent class. The redefinition looks like this:
public class App {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.voice(); // Вывод: Гав
cat.voice(); // Вывод: Мяу
}
}
class Animal { // родительский класс
public void voice() {
System.out.print("Голос животного");
}
}
class Dog extends Animal { // класс-наследник
@Override // Переопределение метода voice() унаследованного от класса Animal в классе-наследнике Dog
public void voice() {
System.out.print("Гав");
}
}
class Cat extends Animal { // класс-наследник
@Override // Переопределение метода voice() унаследованного от класса Animal в классе-наследнике Cat
public void voice() {
System.out.print("Мяу");
}
}
The overridden method must have the same access modifier as its parent, accept arguments as its parent. the parent, and have the return type the same as its parent
I.e.
public class App {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.voice("Шарик", 10); // Вывод: Гав
cat.voice("не Шарик", 7); // Вывод: Мяу
}
}
class Animal {
// Родительский метод имеет возвращаемый тип String. Принимает два параметра, типа String и int
public String voice(String animal_name, int animal_age) {
System.out.print("Гав");
return animal_name;
}
}
class Dog extends Animal{
// Переопределенный метод должен как его родитель, иметь возвращаемый тип String, и принимать параметры как его родитель
@Override
public String voice(String dog_name, int dog_age) {
System.out.print("Гав");
return dog_name;
}
}
class Cat extends Animal {
@Override
public String voice(String cat_name, int cat_age) {
System.out.print("Мяу");
return cat_name;
}
}
Hiding the method:
Hiding methods, roughly speaking, is an "overlap" of the method of the current class, the method of the parent class. It looks like this:
public class App {
public static void main(String[] args) {
Dog.voice(); // Вывод: Гав
}
}
class Animal {
public static void voice() {
System.out.print("звук");
}
}
class Dog extends Animal {
// Метод определенный в классе-наследнике идентичный по сигнатуре с методом родительского класса
public static void voice() {
System.out.print("Гав");
}
}
The method signatures of these two classes are identical, i.e. the parent class Animal
has public static void voice()
and the descendant class Dog
has public static void voice()
. Therefore, calling Dog.voice()
will call the method defined in the class Dog
It is important to note that overlapping requires the same rules as overriding a method.
The overridden method must have the same access modifier as its parent, accept arguments as its parent, and have the return type the same as its parent
I.e.
public class App {
public static void main(String[] args) {
Dog.voice(); // Вывод: Гав
Dog.voice("Шарик"); // Вывод: Шарик говорит гав
}
}
class Animal {
public static void voice() {
System.out.print("звук");
}
}
class Dog extends Animal {
public static void voice() { // Метод перекрывающий унаследованный метод
System.out.print("Гав");
}
public static void voice(String name) { // Отдельный метод класса Dog
System.out.print(name + " говорит гав");
}
}
Consider the use of such methods in your classes
- Using a method without a similar signature
public class App {
public static void main(String[] args) {
Dog.voice(); // Вывод: звук
}
}
class Animal {
public static void voice() {
System.out.print("звук");
}
}
class Dog extends Animal {
public static void dog_voice() {
voice();
}
}
Since in if there is no method implemented in the descendant class that is similar in signature to the parent class, then the method inherited from the parent class is used
- Using a similar signature method
public class App {
public static void main(String[] args) {
Dog.dog_voice(); // Вывод: гав
}
}
class Animal {
public static void voice() {
System.out.print("звук");
}
}
class Dog extends Animal {
public static void voice() {
System.out.print("Гав");
}
public static void dog_voice() {
voice();
}
}
Since the Dog
class now has "its own method" voice()
, it overrides the method inherited from Animal
- Using a method inherited from a parent when there is a method overriding it
public class App {
public static void main(String[] args) {
Dog.dog_voice(); // Вывод: Гавзвук
}
}
class Animal {
public static void voice() {
System.out.print("звук");
}
}
class Dog extends Animal {
public static void voice() { // Метод перекрывающий унаследованный метод
System.out.print("Гав");
}
public static void dog_voice() {
voice(); // Вызов метода voice определенного в классе Dog;
Animal.voice(); // Вызов метода voice определенного в классе Animal
}
}
I want to add the following topics, that the overlap works not only with the methods of the class, but also with its fields. A small example:
public class App {
public static void main(String[] args) {
Dog.animal(); // Вывод: Имя этого животного Собакен
}
}
class Animal {
public static String animal_name = "Нет имени, просто животное";
public static void animal() {
System.out.print("Имя этого животного " + animal_name);
}
}
class Dog extends Animal {
public static String animal_name = "Собакен"; // Перекрывает поле родительского класса Animal
public static void animal() {
System.out.print("Имя этого животного " + animal_name);
}
}
There are cases when we REDEFINE the method, and there are cases when we HIDE the method. In your case, there is a "hiding", not a "redefinition" of the method.
Static methods DO NOT" override " superclass methods. Static methods are able to "hide" a method from a superclass. At first glance, it may SEEM that "redefining" and "hiding" are the same thing. Here is written what is the difference between them.