С неявным повышением в этой строке:
Animal myAnimal = myDog;
Вы ничего не делаете для изменения базового экземпляра myDog
. То, что вы делаете, это присваиваете переменную типа на один уровень выше в дереве наследования. По сути, это ограничивает то, какие методы могут вызываться только теми, которые определены в Animal
, но не меняет способ разрешения этих методов.
Поскольку вы ограничили доступные методы только теми, которые определены в родительском классе Animal
компилятор не может разрешить Dog#bark()
, поскольку это метод Dog
, а переменная myAnimal
определена как тип Animal
, у которого нет метода #bark
.
#move()
- это метод как Animal
, так и Dog
, поэтому он разрешается, но разрешается в метод, определенный в Dog
, поскольку myAnimal
по-прежнему ссылается на экземпляр Dog
, несмотря на то, что он преграждается.