Skip to content

Latest commit

 

History

History
30 lines (22 loc) · 5.08 KB

over-load-ride.md

File metadata and controls

30 lines (22 loc) · 5.08 KB

Введение

В Java все классы неявно наследуются от класса Object. Сделано это для того, чтобы выделить некоторые общие методы, присущие для всех классов, такие как toString(), например.

Но если бы дело ограничивалось только обычным наследованием, это было бы не слишком удобно - как для toString(), так и для других методов. Ведь не всегда то, что мы унаследовали нам подходит - тот же пример с toString().

Для этого в Java используется переопределение и перегрузка методов:

Переопределение и перегрузка (override и overload)

Overriding - переопределение

Переопределение, как следует из названия, это по сути переписывание(переделываете, переопределяете) уже существующего метода, который мы унаследовали от предка. Для примера возьмем 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. Именно поэтому возможность вызова статичных методов на экземплярах считается вредоносной и повсеместно осуждается на практике. Я настроил ИДЕ так, чтобы все подобные вызовы рассматривались как ошибки компиляции и вам того же желаю. Вызов статичных методов класса родителя на классах наследниках - дело вкуса, но мне кажется плохой практикой (как и наследование интерфейсов только ради статичных констант).