Объясните пожалуйста для чего это, если мы создали класс Animal
, потом Cat extends Animal
, для чего создают объекты вида Animal barsik = new Cat();
если могли просто Cat barsik = new Cat();
и это разновидность полиморфизма, или только override
полиморфизм?
Напоминает диалог:
Update
Надеялся, что поймете, но не судьба. Посему буду объяснять:
Судьба кота зависит от точки зрения (или если угодно от Use Case)
Cat
Animal
barsik instanceof Cat
Соответственно, когда вы пишете Animal barsik=new Cat()
- это означает, что вы собираетесь дальше юзать кота как животное, вам достаточен уровень абстракции Animal
. Но, если дальше у вас в коде начинаются операции типа: (Cat )barsik
- значит что-то пошло не так... - вам таки нужен был уровень абстракции Cat barsik=new Cat()
Дальше больше - дальше начинается философия: правильный прогер, всегда должен пользоваться максимальным уровнем абстракции (обратите внимание, что я лично не совсем соглашаюсь с такой философией). Некоторые особо упоротые интервьюеры спецом заваливают несчастного претендента на куске кода типа:
ArrayList<String> strings=new ArrayList<String>();
for(String s: strings)
System.out.println(s);
С вопросом - что в этом коде не так? Правильный ответ:
List<String> strings=new ArrayList<String>();
for(String s: strings)
System.out.println(s);
Для переменной strings
уровень ArrayList<>
излишен, достаточно только интерфейса List
Если мы работает с этими объектами на уровне интерфейса, определённого в абстрактном классе Animal
, то лучше объявлять соответствующую переменную или поле как Animal
, чтобы не быть зависимым от конкретной её реализации, которую можно будет легко изменить в одном месте, не меняя весь остальной код, использующий Animal
. Это и есть преимущество полиморфизма. Если же нам нужно вызывать какие-то методы, которые есть только у Cat
, то нет другого выхода кроме как объявлять соответствующие переменные и поля конкретным классом Cat
или же ввести ещё один абстрактный класс Feline
(род кошачьих в биологии), с дополнительными методами, от которого Cat
и будет наследовать. Таким образом цепочка наследования будет такой Animal -> Feline -> Cat
.
Если очень простым языком, то можно работать с котами класса Cat - заполнить ими массив (ArrayList), производить над ними свойственные котам действия (кормить, поить, вычесывать, водить к ветеринару).
В какой-то момент в вашем кошачьем царстве появляется, например, пара собак класса Dog. Можно, конечно, создать для них отдельный массив ArrayList и никогда не смешивать котов и собак.
Но есть и другой вариант - выделить общие черты кошек и собак в отдельный класс животного (Animal - кличка, возраст, метод покормить), от которого наследовать классы Cat и Dog (чтобы кличка, возраст и покормить были у обоих видов). А когда потребуется покормить всех животных, можно создать массив с классом их родителя ArrayList, в который прекрасно запишутся как кошки (new Cat()), так и собаки (new Dog()), у которых можно будет вызывать общие методы, не задумываясь кого ты конкретно кормишь.
Ответ на вопрос о том, наследование или полиморфизм - тут речь про наследование.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
мне нужно сохранить файл в формате Json, чтобы потом при открытии я мог использовать данные которые сохранил, желательно сохранить файл в конкретную...
Всем привет, все никак не могу понять про префикс и суффикс каждого индекса в массиве! Само понимание не приходит и как следствие реализация...
Как вывести новый масив из елементов в блоке if? Нужно вывести масив из отобраных объектов