Друзья, привет. Разжуйте, пожалуйста, какая разница между кодом, если класс Cat наследует (расширяет) класс Animal?
Cat c = new Cat();
Animal c = new Cat();
Вызовы функции c.makeSound() дают одинаковый вывод в консоль: Meow
Нужно ли создавать объект типа Animal в таком случае?
И является ли в таком случае создание метода makeSound() в классе Cat переопределением (overriding) этого же метода в родительском классе? Весь код:
class Animal {
public void makeSound() {
System.out.println("Grr...");
}
}
class Cat extends Animal {
public void makeSound() {
System.out.println("Meow");
}
}
class Program {
public static void main(String[] args) {
Cat c = new Cat();
c.makeSound();
//Animal c = new Cat();
//c.makeSound ();
}
}
Разница состоит в полиморфизме и динамическом связывании.
Когда вы пишите Animal a = new Cat(), то вы расширяете объект класса Cat до объекта его базового класса Animal (восходящее преобразование).
А суть динамического связывания состоит в том, что всегда вызывается "новая" версия метода makeSound. Именно поэтому при вызове a.makeSound() вызывается версия подкласса Cat, а не суперкласса Animal. Эта связь определяется во время выполнения программы (отсюда и название - динамическое связывание).
Нужно ли создавать объект типа Animal в таком случае?
Если Вы будите создавать только объект типа Animal, то вы не сможете вызвать нужную версию метода makeSound, которая будет печатать Meow.
И да, когда вы пишите метод с такой же сигнатурой в классе-наследнике, то это и есть переопределение (override) метода базавого класса. Важно не сужать уровни доступа при определении метода, иначе нарушается полиморфизм.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости