Коллеги, кто-то может по шагам расписать что происходит в этом коде?
Честно говоря ничего не понял.
Причем, при запуске в консоль выводится:
2
3
а в режиме дебаг:
4
8
Rodriguez
33 уровень
Как работает код?
Обсуждается
Комментарии (16)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
НурланРаботает в ищу работу
12 апреля 2022, 23:17
было скучно и добавил 1 строку :)
static class Hobby implements Desire, Dream {
static int INDEX = 1;
String kill = new Hobby().toString() ;
@Override
public String toString() {
INDEX++;
return "" + INDEX;
}
}
0
Natallia
30 августа 2018, 19:13
Я вижу это так.
INDEX -статическая переменная, т.е. она относится к классу , а не к каждому экземпляру.
При вызове метода toString, значение этой переменной увеличивается на 1.
Вот и получается, что при запуске программы:
1. В строке 9 создается экземпляр класса Hobbie (Dream.HOBBIE=new Hobbie() исходя из строки 17) и он вызывает метод toString, который увеличивает на единицу статическую переменную INDEX и выводит ее значение на экран.
После этого INDEX приобретает значение 2
2. В строке 10 снова создается новый объект Hobbie, который снова вызывает метод toString, который еще раз увеличивает INDEX на 1. После чего INDEX становится равным 3
Если бы метод toString вызывался еще несколько раз, то значение INDEX бы увеличивалось еще на единицу каждый раз при вызове этого метода. Т.к. это статическая переменная, то она ее значение не сбрасывается при создании нового объекта, она относится к классу.
Как работает дебаг не знаю, не разбиралась еще в этом вопросе.
+6
hidden #1294817
14 сентября 2018, 11:18
а почему программа вообще компилируется если в классе не прописаны методы унаследованных интерфейсов?
0
Стас ПасинковSoftware Developer в ZipyMaster
22 сентября 2018, 01:57
в этих интерфейсах нет методов.
есть только статическая переменная HOBBIE
0
Dima
24 января 2019, 13:42
скажите, а зачем нам эта переменная?
Зачем нам вообще создавать экземпляр класса-наследника из интерфейса?
Для того, чтобы создавать экземпляры кодом Dream.HOBBY., вместо Hobby HOBBY = new Hobby(); ??? Но ведь в таком случае мы можем создать только 1 экземпяр?!
Ведь даже если написать
Dream.HOBBY.
Dream.HOBBY.
Dream.HOBBY.
Ведь будет только одна переменная HOBBY с ссылкой на один новый экземпляр Hobby
0
Стас ПасинковSoftware Developer в ZipyMaster
24 января 2019, 15:18
наверное для того, чтобы вы с этим всем столкнулись и разобрались))
и чтоб не было потом "ой, а что, так тоже можно было?"))
0
Dima
25 января 2019, 09:47
Стас, спасибо за ответ. Уточните пожалуйста, те доводы, что я привожу правильны?
1) Мы можем создавать обьект кодом Dream.HOBBY.?
2) если да, то не больше одного?
3) а суть этой переменной в интрфейсе в полиформизме? переопределить же ее можо будет в классе наследнике?
+1
hidden #598481
25 января 2019, 10:12
Вчера хотел тебе ответить, но коротко не получалось, а длинно было лень.
HOBBY большими буквами - это переменная в интерфейсе Dream, и поскольку она в интерфейсе, она по умолчанию статическая и неизменяемая.
Раз в интерфейсе есть переменная, то она есть и в каждом классе, который его реализует. То есть т.к. хобби реализует интерфейс Dream, то у каждого объекта класса хобби тоже есть переменная HOBBY.
А еще в каждом хобби есть статическая (одна на всех) переменная индекс, которая растет с каждым вызовом toString.
То есть если ты создаешь еще один объект класса Хобби, то у него есть переменная ХОББИ в которой создается еще один объект класса Хобби и т.д.
Смотри:
Вывод будет 2 3 4 5 6 - индекс постоянно растет при каждом выводе на экран.
Просто авторы продемонстрировали, какую рекурсию можно сделать, поместив объект класса в статическую переменную внутри этого класса, и сделали это, используя интерфейс и наследование.
+32
Dima
25 января 2019, 13:47
Спасибо большое за развернутый ответ!
"Раз в интерфейсе есть переменная, то она есть и в каждом классе, который ее реализует. То есть т.к. хобби реализует интерфейс Dream, то у каждого объекта класса хобби тоже есть переменная HOBBY."
Скажите, но разве при наследовании переменной HOBBY из интерфеса, она не наследуется, как public static final , а значит, она становится одна на все обьекты класса Hobby, как INDEX.
Таким образов ее можно вызывать Hobby.HOBBY или, как у вас oneMoreHobby.HOBBY.
При данном вызове создается новый обьект Hobby со ссылкой на статическую переменную HOBBY.
И чтобы нам вызвать переменную HOBBY из новоиспеченного обьекта, мы пишем oneMoreHobby.HOBBY.HOBBY и так далее.
Не понимаю тогда вот что, при вызове переменной HOBBY ей присваивается ссылка на новый обьект (назовем его А1). Потом из этого обьекта мы вызываем все ту же (она же статик) переменную HOBBY, которая создает новый обьект (А2). Но тк HOBBY статик, то после последней операции в ней должна лежать ссылка на (А2), а ссылка на (А1) должна стать мусором. Если так, то oneMoreHobby.HOBBY. (А1) HOBBY. (А2) HOBBY не должно иметь смысла, тк уже невозможно вызвать HOBBY с сылкой на (А1).
Скажите, пожалуйста, где моя ошибка?
ИЛИ
тк она переменная final , то в ней всегда будет лежать ссылка на (А1), а значит мы из (А1) будем создавать (А1)?? и это некий замкнутый круг не выходящий за пределы 2х обьектов (*или обьекта и переменной)? тоесть командой oneMoreHobby.HOBBY..HOBBY.HOBBY.HOBBY мы просто ходим по кругу не увеличивая при этом кол-во обьектов ??
ПС. судя по тому, что значит рекурсия, то второй вариант правильный?
+1
hidden #598481
25 января 2019, 14:04
Последний абзац правильный.
Каждый раз, когда ты сам пишешь new Hobby(), ты создаешь новый объект. И внутри каждого из этих объектов в поле HOBBY лежит тот самый объект, который создался при создании интерфейса.
Смотри, чтобы не запутаться, мы можем переделать метод toString(), чтобы он снова начал возвращать нам хеш-код объектов.
и смотрим на вывод. Видим, что в строчке 1 тот же самый хеш-код внутри, что и в строчках 4-6
+13
Dima
25 января 2019, 14:39
Огромное спасибо. Механизм я понял, а пример (смысл) применения не могу придумать. У вас есть идеи?
ПС. Я поставил счетчик в конструктор, чтобы узнать запускается ли он, когда мы вот так по кругу гоняем... Нет, не запускается. Поэтому не понимаю, зачем ??
ВСЕ ВСЕ, Спасибо за твой ответ, сенсей!
Очень помог.
А рекурсия вот тут хорошо описывается Рекурсия в Java
+2
hidden #598481
25 января 2019, 14:53
Нет, я без понятия. Тут какие-то тонкие материи демонстрируются, мне тоже немного голову взрывает это дело :) Возможно, если где-то пригодится, то такая реализация покажется настолько логичной, что и не вспомнишь, сколько вопросов это вызвало в первый раз.
Про конструктор понятно, новые объекты же не создаются, с чего накручиваться счетчику
+1
hidden #598481
25 января 2019, 14:56
да какой я сенсей, я также сижу и ковыряюсь, пытаясь понять ;)
Про рекурсивный вызов методов это еще ясно, а вот это поле, ссылающееся само на себя, все-таки немного сдвигает крышу.
+1
Fed Or
22 ноября 2021, 18:15
@vk @Dima - спасибо за обсуждение. С третьего раза вроде понял. хотя по началу просто туман)
0
RodriguezExpert
8 мая 2018, 18:56
+1
Ваня Жуков
8 мая 2018, 04:46
Какой код?
+4