Всем привет) В одной из лекций был пример наследования интерфейса
public class Telegram implements Messenger{
//...методы
}
public class Client{
private Messenger messenger;
public Client(){
this.messenger=new Telegram();
}
}
К сожалению, не записала себе, где этот пример был, а теперь не могу найти лекцию. Не понимаю, что это за переменная интерфейса такая странная - выглядит, как объект. Хотя интерфейс, по идее, высшая степень абстракции... .
hidden #2444690
26 уровень
Переменная интерфейса. Не могу понять
Комментарии (26)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Justinian Judge в Mega City One Master
3 декабря 2020, 10:23
Вопросы по джава кору лучше задавать в секции Помощь. Там можно задавать любые вопросы, связанные с джавой и программированием. Здесь на форуме задаются более абстрактные или не связанные с джава кором.
Cat cat = new Cat();
Тип переменной Кот
Имя переменной кот
new Cat() создание на базе чертежа (класса Кот) экземпляра объекта - то есть выделяется область памяти, присваивается уникальный идентификатор (Ссылка) именно на этого конкретного кота, у кота есть определенное состояние :
name = Vasya
age = 5
и тд
отдельно таблица с доступными методами и тд. Это экземпля объекта.
То есть объект у нас там, где ключевое слово new.
Если мы говорим про
Сat cat
Animal cat
Messenger messenger
List<String> list
то мы говорим, что тип переменной может быть:
-обычный класс
-абстрактный класс
-интерфейс
Это не объект.
Это тип переменной. Что переменная может хранит.
Абстрактный классы и интерфейсы нельзя делать экземпляры объектов, но они могут задавать контракт:
например
abstract class Animal {
public abstract void doSound;
}
или интерфейс List, говорит что должны быть методы add, size и тд.
И это значит, что в переменную можно поместить ссылку на любой объект, который имплементирует интерфейс или наследует абстрактный класс.
Благодаря этому мы можем использовать полиморфизм.
Например, Человек, как слово, или допустим ты и я студенты, Студент.
Человек и Студент это конкретный объект? Нет. Это абстракция, нету одного единственного человека или студента, это просто тип.
Ты конкретная реализация. Я конкретная реализация.
Поэтому можно написать:
Human alexandra = new Alexandra();
Human justinian = new Justinian();
Мы конкретные объекты, но у нас есть руки, ноги, мы имплементируем интерфейс Человек.
И удобно, когда мы можем группировать обработку объектов по их типу, когда мы отбрасываем ненужные детали, что ты живешь там, а у меня родители те, ты играешь на трубе, а я на ударных.
А мы используем общие характеристики, и одинаково обрабатывать данные
+3
Justinian Judge в Mega City One Master
3 декабря 2020, 10:28
Например, можешь создать:
abstract class Animal {
public String name;
public abstract void doSound();
public String getName() {
return name;
}
}
и 5 классов, Cat, Dog, Hedgehog, Mouse, Parrot
которые наследуются и реализуют метод.
И теперь вопрос, как без использования переменной типа Animal , а исключительно через
Сat cat = new Cat() ..
Ты, создашь по одному экземпляру каждого типа объекта:
1. Вызовешь у всех doSound();
2. выведешь на экран имя каждого объекта.
Без использования супертипа Animal
+3
Justinian Judge в Mega City One Master
3 декабря 2020, 10:32
С использованием супертипа понятно:
List<Animal> animals = new ArrayList();
а вот как без супертипа - интерфейса /абстрактного класса сделать? Только через поштучное создание, что неудобно, а если 1000 объектов?
Либо через List<Object> но это типонебезопасный подход, могут быть ошибки, ведь мы можем поместить в такой список объект BufferedReader и при попытке вызова doSound() будет исключение.
Поэтому для полиморфизма и есть возможность использовать тип переменной.
Которая указывает каким требованиям, должна соответствовать переменная, которая может быть помещена.
Либо наследоваться от абстрактного класса
Либо наследоваться от конкретного класса указанного в типе
Либо реализовать указанный интерфейс
И благодаря этому, мы можем работать с целыми группами РАЗНЫХ имплементаций, разных объектов, как с одним типом, значительно упрощая групповую/конвеерную обработку данных +4
hidden #2444690
3 декабря 2020, 10:53
То есть, получается, что полиморфизм - это обобщение по какому-то признаку, в данном случае, по признаку принадлежности к интерфейсу, и, соответственно, работа идет дальше уже с этой обобщенной группой. Теперь пытаюсь сообразить, как выстроить в голове) У меня раньше полиморфизм воспринимался только в одну сторону) Что это, например, разные подтипы одного и того же вида животных или реализации одного и того же метода (хотя перегрузка - это ненастоящий полиморфизм, насколько помню). В общем, поняла, это как перевернутое дерево: обобщение -< ветви реализаций) Спасибо) Про раздел "Помощь" поняла)
0
hidden #2322530
3 декабря 2020, 11:35
Полиморфизм в первую очередь, это возможность работать с разными типами объектов одинаково. например есть TreeMap, а есть HashMap, так как они оба наследованы от Map, то можно одинаково работать и с тем, и с другим. полиморфизм гарантирует, что поведение разных типов классов унаследованных от одного интерфейса например будут иметь одинаковое поведение.
есть Перегрузка, есть Перезагрузка.
настоящий полиморфизм и то и то) я долго тогда спорил на эту тему, но в итоге нашёл много информации по этому.
Перегрузка - Статический полиморфизм
Переопределение - Динамический полиморфизм.
разница в чем?
при перегрузке правильность работы проверяется на этапе компиляции, чтобы типы аргументов соответствовали. неправильно напишешь код, не скомпилируется даже.
при Переопределении правильность работы проверяется во время работы. потому что JVM при компиляции не может знать, какие именно объекты туда будут передаваться. (классы можно например на лету подгружать)
можно указать один входной аргумент, например интерфейс. и это будет гарантировано что все объекты наследованные от этого интерфейса будут работать правильно.
+1
Justinian Judge в Mega City One Master
3 декабря 2020, 11:45
Поли - много
форм - форма
Полиморфный , то есть имеющий много обличий.
Та же перегрузка:
имя одно, а форм много.
Или оверрайдинг/переопределение:
один и тот же метод может по разному переопределен в разных наследниках.
Или как говорил Бьорн Страустрап, один интерфейс много реализаций.
Это инструменты полиморфизма. А как следствие, мы можем работать с различными подтипами.
Чтобы это было возможно, конечно нужно какое-то абстрактное обобщение, те же абстрактные классы, или интерфейсы.
Это не самая простая тема для осознания, со временем уляжется, пока что фокусируйся на решении задач. По мере роста объема практики у тебя будет необходимый материал, который позволит подвести черту и сделать выводы, но для этого нужно кодить. Теория без практики сама в голову не залезет, это сложно. +1
hidden #2444690
3 декабря 2020, 12:07
Хорошо, да, поняла) Про перегрузку и перезагрузку поняла и запомнила, спасибо) К сожалению, сейчас уже не вспомню, чем аргументировали то, что перегрузка является ложным полиморфизмом, думаю, в этом нет необходимости) Ваш ответ мне больше нравится)
0
hidden #2444690
3 декабря 2020, 12:15
Да, спасибо) Просто, видите, про явление полиморфизма знаю, а в реальном примере его не увидела. Если бы меня носом не ткнули) Хотя, с другой стороны, в другом проявлении в другом примере, возможно, опять не увижу и не узнаю... В общем, ушла решать задачи)
0
hidden #2322530
3 декабря 2020, 12:17
я тогда спорил как раз что перегрузка не является полиморфизмом.
ведь полиморфизм в первую очередь это или наследование, или реализация интерфейсов.
и тогда я упорно доказывал, что как перегрузка может быть полиморфизмом, если перезагрузку ты можешь использовать только если наследуешь или реализуешь интерфейс (наследуешь от интерфейса).
а перегрузку ты можешь использовать когда хочешь и где хочешь. даже не наследуешь ни от чего) (ну наследование от Object в расчёт не берём)
к чему потом привело гугление и чтение, что перегрузка это полиморфизм.
всё почему? потому что ты по сути описываешь одинаковое поведение с разными входными данными.
ну а дальше я уже нагуглил понятия статического и динамического полиморфизма, и объяснение, как это работает.
+2
hidden #2322530
3 декабря 2020, 12:18
вот пример полиморфизма через интерфейсы и переопределение .
как видишь тут в методе мы передаём интерфейс. а за счёт того, что работает полиморфизм, и все наследники реализуют методы в обязательном порядке. мы можем гарантировать, что во время работы все объекты, переданные в аргументе будут вести себя одинаково вне зависимости от их типа. а за счет переопределения каждый объект будет вести себя по особенному.
+2
hidden #2444690
3 декабря 2020, 12:30
А если мы не переопределяем, а перегружаем (overloading) методы, там же не будет наследования, это может происходить в рамках одного класса, например, перегруженные конструкторы. Это же тоже полиморфизм?
И еще вопрос. Если я буду учиться писать "истории" в коде, как вот ты пишешь и Justinian, просто из головы описывать окружающий мир таким образом, это же будет полезно? Как вы вообще это делаете? Да еще и так быстро))
0
hidden #2322530
3 декабря 2020, 12:37
это может происходить в рамках одного класса, например, перегруженные конструкторы. Это же тоже полиморфизм?
статический полиморфизм получается. но перегрузка это такой полиморфизм, про который стоит знать, но не стоит его им называть) ибо холиварная тема. отвечать на неё обычно стоит так, как можешь доказать. если сможешь доказать что это не полиморфизм, то говори что нет, не полиморфизм)
конструктор это такой же обычный метод, просто он в отличие от других имеет ряд строгих правил, и всегда возвращает ссылку на новый объект.
И еще вопрос. Если я буду учиться писать "истории" в коде, как вот ты пишешь и Justinian, просто из головы описывать окружающий мир таким образом, это же будет полезно?
сейчас я этот код не писал, я его из спора скопировал. а так полезно, для закрепления.
Как вы вообще это делаете? Да еще и так быстро))
с опытом придёт.
моё личное мнение, что перегрузка всё равно не является полиморфизмом)
0
hidden #2444690
3 декабря 2020, 12:39
))))ок) хорошо))
0
Justinian Judge в Mega City One Master
3 декабря 2020, 17:24
ой, пятничные темы пошли 😀
0
hidden #2444690
3 декабря 2020, 17:59
)))
0
VladimirMaster
4 декабря 2020, 05:39
Overload есть в Java, а про перезагрузку не слышал даже. Что это еще за хухэ? 🙂😉
0
hidden #2444690
4 декабря 2020, 06:07
Это такое переопределяющее хухэ))
0
VladimirMaster
4 декабря 2020, 06:33
Ты меня не убедила. Подробнее плиз. Мне кажется в Java нет перезагрузки. Есть перегрузка (overload). А, что такое перезагрузка в Java? 🤔
+1
hidden #2322530
4 декабря 2020, 06:50
да ты прав. поправлю. перегрузка и переопределение
+2
hidden #2444690
4 декабря 2020, 06:50
Если принять во внимание тот факт, что в российском IT пространстве нет чётко задокументированной терминологии по этому вопросу, в приватный беседах допускается вольный перевод, если это не мешает пониманию предмета у собеседников. А вы, Владимир, в беседе не участвовали:р
0
hidden #2322530
4 декабря 2020, 07:05
приватная, это в личке, а тут всё общее.
+1
hidden #2444690
4 декабря 2020, 07:10
Ок, убедили)
0
VladimirMaster
4 декабря 2020, 08:39
Это, как раз мешает пониманию и ведет к запутыванию итак не очень простой темы (override and overload).
0
hidden #2444690
4 декабря 2020, 08:49
Хорошо, я больше не буду, обещаю исправиться)
0
Алексей
3 декабря 2020, 10:16
Полиморфизм. Messenger messenger ссылка на объект любого класса который реализует интерфейс Messenger. И соответственно у переменной messenger можно вызывать только те методы которые объявлены в интерфейсе Messenger. А уж реализация их будет зависеть от того на какой объект ссылается messenger
+2
hidden #2444690
3 декабря 2020, 10:19
Понятно) Спасибо)
0