В Java
все классы неявно наследуются от класса Object
.
Сделано это для того, чтобы выделить некоторые общие методы, присущие для всех классов, такие как toString()
, например.
Но если бы дело ограничивалось только обычным наследованием, это было бы не слишком удобно - как для toString()
, так и для других методов.
Ведь не всегда то, что мы унаследовали нам подходит - тот же пример с toString()
.
Для этого в Java
используется переопределение и перегрузка методов:
Переопределение, как следует из названия, это по сути переписывание(переделываете, переопределяете) уже существующего метода, который мы унаследовали от предка.
Для примера возьмем toString()
- метод возвращающий строковое представление объекта - и следующую модель:
class Person {
private String name;
private int age;
//code
}
Если не переопределять метод, то вывод будет в виде Person@125125d
.
Вопрос Может ли статический метод быть переопределён? Может ли он быть перегружен? Ответ скрыть Перегружен - да. Всё работает точно так же как и с обычными методами - 2 статичных метода могут иметь одинаковое имя если кол-во аргументов ИЛИ их типы отличаются. Переопределён - официальный ответ: нет. Т.к. переопределение подразумевает выполнение метода Б при вызове метода А, если Б переопределяет А. Статичный вызов точно определяет, какой именно метод будет выполнен. Но! Джава позволяет вызывать статичный метод класса А на экземпляре класса А, или на любом наследованном от него классе и его экземпляре. Такое поведение вызывает больше проблем, чем пользы, и создаёт видимость переопределения статичных методов. Пример: 1. Класс A объявляет метод "public static void some()" 2. Класс B наследован от А 3. Класс C наследован от B Вызов метода "C.some()" выполнит метод из класса А. Но если класс B объявит точно такой же метод "public static void some()", то вызов "C.some()" выполнит метод из класса B. Такое поведение называется "сокрытием" и работает по ТОЧНО таким же правилам, как и переопределение - одинаковая сигнатура, такой же или более широкий доступ и такие же или более узкие исключения и возвращаемое значение. Т.е. (!) при написании статичного переопределяющего метода нужно придерживаться точно таких же ограничений, как и с обычным методом, но он не будет участвовать в полиморфизме - если ваш метод принимает параметр "A a" и вызывает на полученном объекте статичный метод "a.some()" то всегда будет вызван именно метод класса A, даже если передан был объект класса B или C. Именно поэтому возможность вызова статичных методов на экземплярах считается вредоносной и повсеместно осуждается на практике. Я настроил ИДЕ так, чтобы все подобные вызовы рассматривались как ошибки компиляции и вам того же желаю. Вызов статичных методов класса родителя на классах наследниках - дело вкуса, но мне кажется плохой практикой (как и наследование интерфейсов только ради статичных констант).