1. Но и это еще не все
Предположим, в классе Cow есть метод printAll(), который вызывает два других метода. Тогда код будет работать так:
| Код | Описание |
|---|---|
|
|
|
На экран будет выведена надпись: |
Обратите внимание: когда вызывается метод printAll(), написанный в классе Cow, у объекта типа Whale, используется метод printName класса Whale, а не Cow.
Главное — не в каком классе написан метод, а какой тип (класс) объекта, у которого этот метод вызван.
Наследовать и переопределять можно только нестатические методы. Статические методы не наследуются и, следовательно, не переопределяются.
Вот как выглядит класс Whale после применения наследования и переопределения методов:
|
Вот как выглядит класс Whale после применения наследования и переопределения метода. Ни о каком старом методе printName мы и не знаем. |
2. Приведение типов
Тут есть еще более интересный момент. Т.к. класс при наследовании получает все методы и данные класса-родителя, объект этого класса разрешается сохранять (присваивать) в переменные класса-родителя (и родителя родителя, и т.д., вплоть до Object). Пример:
| Код | Описание |
|---|---|
|
На экран будет выведена надпись: |
|
На экран будет выведена надпись: |
|
На экран будет выведена надпись: Метод toString() унаследован от класса Object |
Это очень ценное свойство: немного позже вы поймете, как это использовать на практике.
3. Вызов метода объекта
При вызове метода у переменной, реальный метод вызывается у объекта. Этот механизм называется динамической диспетчеризацией методов.
Вот как это выглядит:
| Код | Описание |
|---|---|
|
На экран будет выведена надпись: |
|
На экран будет выведена надпись: |
Обратите внимание, что на то, какой именно метод printName() вызовется, от класса Cow или Whale, влияет не тип переменной, а тип объекта, на который она ссылается.
В переменной типа Cow сохранена ссылка на объект типа Whale, и будет вызван метод printName(), описанный в классе Whale.
Это не очень очевидно. Запомните главное правило:
Набор методов, которые можно вызвать у переменной, определяется типом переменной. А какой именно метод/какая реализация вызовется, определяется типом/классом объекта, ссылку на который хранит переменная.
Вы будете постоянно сталкиваться с этим, так что чем раньше запомните, тем лучше.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ