Напряги извилины!

  • 7
  • Недоступна
Метод printName должен выводить имя собственного объекта, т.е. "The Darkside Hacker". Сделайте минимум изменений.
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (84)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
aleksdenni
Уровень 37, Полтава, Украина
7 сентября, 18:35
Я переменную сразу статиком сделал , оказалось ошибка .
Андрей Бугаев
Уровень 25
22 августа, 15:45
Никакой приватности))))
Дмитрий Б.Г.
Уровень 31, Кременчуг, Украина
15 августа, 13:29
Пара ссылок на тему связывания методов, чтобы понять что происходит: 1. English 2. Русский (JavaRush)
Максим Дудин
Уровень 29, Калининград
2 июня, 16:43
ну вот взяли сами и подсказали ... в требованиях.. Сам бы долго искал подвох 🙂
aleksdenni
Уровень 37, Полтава, Украина
7 сентября, 18:37
Постоянно забываю их читать😺
Stealth
Уровень 26, Москва
29 апреля, 20:44
Не очень понял, почему нельзя обратиться к методу наследуемого класса через super, типа:
new Solution("The Darkside Hacker") {
            void printName() {
                System.out.println(super.getName());
            }
        }.printName();
а нужно именно менять модификатор метода? В таком виде прекрасно работает и, как по мне, вполне логично. В отличие от игр с модификаторами.
Дмитрий Яковенко
Уровень 35, Москва
30 апреля, 05:42
Вызывая метод super.getName(), ты просто вызываешь метод предка. А у нас задачи на вложенные классы. Нас учат понимать, какие методы и переменные внешние, а какие вложенные. И как к ним обращаться, и как их не путать друг с другом. А то можно было бы вообще написать: System.out.println(getName("The Darkside Hacker")); Решает же задачу?)) И никакой путаницы с предками/вложенными! А вообще краткий вывод этой задачи - всегда явно указывай this. Ведь указав его, мы бы сразу увидели, что у него нет метода getName() (он есть только у внешнего класса).
Кирилл
Уровень 35, Москва, Россия
19 марта, 21:10
Задача Огонь! А популярные комментарии к ней, делают из неё Атомный взрыв. Который, надеюсь, теперь не будет сниться по ночам. )
Andrei Po
Уровень 32
19 января, 06:26
пошагово, что происходит. шаг 1: создаётся базовый класс_1 с именем "Риша" new Solution("Риша") и у класса_1 вызывается метод .sout(); (два действия я объединил в один шаг, для очевидности объяснения, и чтоб не путаться с номерацией классов и шагов. очерёдность тоже не строгая). шаг 2: внутри метода шага 2 - создаётся локальный анонимный внутренний класс_2, а значит, шаг 3: внутри локального внутреннего класса_2 из шага 2 - создаётся ещё один базовый класс_3 new Solution(), но с именем "The Darkside Hacker". класс_2 шага 2 содержит в себе класс_3 как родительский (так как анонимные классы extends (расширяют) те классы, на базе которых они созданы), т.е. у класса 2 будет доступ к public и protected методам класса_3 (но не к private). с другой стороны, класс_2 внутренний по отношению к классу_1, т.е. имеет доступ и к private методам класса_1. шаг 4: из инстанса локального анонимного класса_2 шага 2 вызывается метод .printName(), который был переопределён при создании этого класса_2. при этом запускается private метод getName(). так как метод getName() - private, то инстанс локального класса_2 не видит этот метод в контексте содержащегося внутри класса_2 родительского класса_3 (с именем "The Darkside Hacker"), но, с другой стороны инстанс локального класса_2 видит private метод getName() в контексте класса_1 ( с именем "Риша"), т.к. внутренний класс видит и private методы внешнего. шаг 5. меняя доступ нужного метода мы меняем видимость методов в нужных контекстах. как-то так. (финал пишу немного размыто, а то мои коменты что-то последнее время стали удалять, апеллируя тем, что свечу решения, хотя уйма других коментов с описанными решениями - висят себе и дальше, колышутся на ветру :)
Max Pankov java dev в tsc
11 октября 2020, 19:45
Долго пытался понять описанное комментаторами. Сам понял только додумывая вышеописанное: 1) У нас классы находятся сразу в 2 связях - внешний/внутренний, родитель/наследник Благодаря этому мы видим приватные методы. (это описано у предыдущих комментаторов) 2) Когда мы создаем внутри sout внутренний объект, у него не будет своего метода getName, потому что метод в классе-родителе приватный. Он обратится как внутренний класс к внешнему и возьмет name из внешнего А когда мы сделаем его публичным, во внутреннем классе появятся свой собственный метод getName
Andrej Kostin
Уровень 27, Рига, Латвия
12 октября 2020, 11:11
Верно, так как анонимные классы не являются экземплярами класса, а его насладниками, соответственно приватные метода не будут наследоваться.
Сергей
Уровень 35, Киров, Россия
2 ноября 2020, 20:20
Получается что любой private метод в классе является косвенно final. Так как нельзя получить доступ к закрытому методу, то нельзя и переопределить его
Илья
Уровень 41, Санкт-Петербург, Россия
28 ноября 2020, 11:30
тогда почему, если в анонимном классе написать новый метод и вызвать его, а не getName()
private String getOtherName() {
                return name;
            }
мы все равно видим на экране "Риша"? Значит дело не только в этом. Короче просто не надо писать такой код в жизни, вот и все
Pig Man Главная свинья в Свинарнике
30 ноября 2020, 18:40
Я тоже не особо понял. Нет, ок, тут:
new Solution("The Darkside Hacker") {
    void printName() {
        System.out.println(getName());
    }
}.printName();
мы фактически создаем объект класса наследника от класса Solution, просто этого не видим. Наследник не может получить приватные поля и методы родителя, соответственно, у него нет ни метода getName(), ни самого поля name, так как от Solution он их не получил. Получается, у этого нового класса есть только один метод printName(), потому что его мы ему выдали. Тогда каким образом мы можем вообще передавать в конструктор значение "The Darkside Hacker"? Передавать куда? У этого анонимного класса нет такого поля, как name. И откуда там "Риша" вообще взялся? Это вообще другой экземпляр класса
Pig Man Главная свинья в Свинарнике
30 ноября 2020, 18:47
А, дошло. Тут присутствует также связь между вложенным и внешним классом. Из-за такой каши фиг поймешь, что происходит. Этот анонимный класс, видимо, реально создается внутри Solution, а значит, он является вложенным. А вложенный класс, помня с предыдущих уроков, может спокойно залезть в поля и методы внешнего класса, даже если они приватные. Вот отсюда и "Риша". Это значение из внешнего класса, полученное из метода этого же внешнего класса
it0088
Уровень 40, Худжанд, Таджикистан
6 августа 2020, 11:23
Заключение: наш анонимный класс он и наследник и внутренний класс, класса Solution когда метод у нас private анонимный класс, вызывает private getName() как внутренний класс можете проверить вот так System.out.println(Solution.this.getName()); System.out.println(this.getName()); // думаю тут должно стать ясно если метод сделаем public анонимный класс будет действовать как наследник
Artur
Уровень 40, Tallinn, Эстония
Expert
22 октября 2019, 16:48
Простым языком: new Solution("Риша").sout(); заходим в метод, и видим там класс - наследник, с другим именем в параметрах конструктора. System.out.println(getName()); заходим в приватный геттер (странно, правда?) внешнего класса а не в унаследованный, потому что не можем унаследовать приватный метод, но можем увидеть приватный метод внешнего класса. Поэтому печатаем имя внешнего класса, ведь это его геттер. То же самое будет, если наш анонимный класс не будет наследником внешнего. А нам-то нужно распечатать свое имя, а своего геттера, то у нас нету, пичалько... Что же делать? Для валидатора - выполнить последнее условие ТЗ. Другой способ - достучаться до "папаши-скупердяя", через super.getName() Сердце отца - не камень, поэтому даст попользоваться разок )) Но у валидатора сердце - камень, поэтому используйте первый вариант.
Shamil
Уровень 34, Россия
6 апреля 2020, 04:03
объясните,пожалуйста,почему класс-наследник? Ведь это объект того же класса. ещё мне взрывает мозг вот что... с самого начала говорилось о том,что к private переменным и методам доступа нет. А тут конструкция new Solution("Риша").sout() - где sout это private метод. Внутри него ведь создается объект анонимного класса с переопределенным методом, в котором this.getName ссылается уже на свою собственную переменную?
public class Solution {
    private String name;

    Solution(String name) {
        this.name = name;
    }

    public String getName() {//сделал public
        return name;
    }

    private void sout() {
        new Solution("The Darkside Hacker") {
            void printName() {
                System.out.println(this.getName());//добавил this
            }
        }.printName();
    }

    public static void main(String[] args) {
        new Solution("Риша").sout();
    }
}
Artur
Уровень 40, Tallinn, Эстония
Expert
6 апреля 2020, 07:21
Наследник он потому, что это объект анонимного локального класса с добавленным новым методом. То есть это уже объект другого класса, он стал другим, когда мы добавили этот новый метод. Что касается доступа к приватным полям и методам, то просто оставлю здесь эту цитату:
У локального класса есть доступ ко всем (даже приватным) полям и методам внешнего класса: и к статическим, и к нестатическим.
Взято из этой лекции: https://javarush.ru/groups/posts/2190-vnutrennie-klassih-v-lokaljhnom-metode UPD Это был ответ для Shamil на вопрос, который почему-то выпилился ( ͡° ͜ʖ ͡°) Суть вопроса была в том, что вроде-бы это объект того же класса, почему тогда он наследник, и почему имеет доступ к приватному методу внешнего класса.
Shamil
Уровень 34, Россия
6 апреля 2020, 12:08
ааа... вот этот ньюанс пропустил, или из головы вылетело. Спасибо.
Roman
Уровень 35, Россия
16 апреля 2020, 07:59
Спасибо тебе, добрый человек.
wan-derer.ru
Уровень 40, Москва, Россия
28 сентября 2020, 17:25
<<потому что не можем унаследовать приватный метод>> Почему не можем? Он же не final