Наследование java [дубликат]

111
24 декабря 2021, 17:30
На этот вопрос уже дан ответ здесь:
Композиция и наследование (1 ответ)
Закрыт 2 года назад.

Объясните пожалуйста для чего это, если мы создали класс Animal, потом Cat extends Animal, для чего создают объекты вида Animal barsik = new Cat(); если могли просто Cat barsik = new Cat(); и это разновидность полиморфизма, или только override полиморфизм?

Answer 1

Напоминает диалог:

  • Боб: у меня есть кот
  • Алиса: О, у тебя есть животное?
  • Боб: нет, у меня кот
  • Алиса: ну он же кот - значит животное?
  • Боб: эмм... это полиморфизм или абстракция?
  • Бабушка: хватит уже, он Барсик и он член семьи!

Update

Надеялся, что поймете, но не судьба. Посему буду объяснять:

Судьба кота зависит от точки зрения (или если угодно от Use Case)

  1. Для Боба, который собирается его тискать и гладить - кот безусловно Cat
  2. Для Алисы, которая даже и не знала о его существовании - он еще один Animal
  3. Для бабушки - он не просто кот, а конкретно 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

Answer 2

Если мы работает с этими объектами на уровне интерфейса, определённого в абстрактном классе Animal, то лучше объявлять соответствующую переменную или поле как Animal, чтобы не быть зависимым от конкретной её реализации, которую можно будет легко изменить в одном месте, не меняя весь остальной код, использующий Animal. Это и есть преимущество полиморфизма. Если же нам нужно вызывать какие-то методы, которые есть только у Cat, то нет другого выхода кроме как объявлять соответствующие переменные и поля конкретным классом Cat или же ввести ещё один абстрактный класс Feline (род кошачьих в биологии), с дополнительными методами, от которого Cat и будет наследовать. Таким образом цепочка наследования будет такой Animal -> Feline -> Cat.

Answer 3

Если очень простым языком, то можно работать с котами класса Cat - заполнить ими массив (ArrayList), производить над ними свойственные котам действия (кормить, поить, вычесывать, водить к ветеринару).

В какой-то момент в вашем кошачьем царстве появляется, например, пара собак класса Dog. Можно, конечно, создать для них отдельный массив ArrayList и никогда не смешивать котов и собак.

Но есть и другой вариант - выделить общие черты кошек и собак в отдельный класс животного (Animal - кличка, возраст, метод покормить), от которого наследовать классы Cat и Dog (чтобы кличка, возраст и покормить были у обоих видов). А когда потребуется покормить всех животных, можно создать массив с классом их родителя ArrayList, в который прекрасно запишутся как кошки (new Cat()), так и собаки (new Dog()), у которых можно будет вызывать общие методы, не задумываясь кого ты конкретно кормишь.

Ответ на вопрос о том, наследование или полиморфизм - тут речь про наследование.

READ ALSO
сохранение в Json

сохранение в Json

мне нужно сохранить файл в формате Json, чтобы потом при открытии я мог использовать данные которые сохранил, желательно сохранить файл в конкретную...

183
ClientServer App Java

ClientServer App Java

Друзья просьба помочь понять почему не компилируется код сервера

109
Понимание: Длина префикса

Понимание: Длина префикса

Всем привет, все никак не могу понять про префикс и суффикс каждого индекса в массиве! Само понимание не приходит и как следствие реализация...

162
Как вывести новый масив

Как вывести новый масив

Как вывести новый масив из елементов в блоке if? Нужно вывести масив из отобраных объектов

169