JavaRush /Java блог /Архив info.javarush /Вложенные, локальные и анонимные классы
WhatNick
17 уровень

Вложенные, локальные и анонимные классы

Статья из группы Архив info.javarush
Всем доброго времени суток! Стал глубже копать разновидности классов и написал код, который содержит класс. Этот класс содержит метод main() и статический вложенный класс. Статический вложенный класс содержит метод. Метод создает локальный класс. Локальный класс имеет метод, который создает анонимный класс обрамляющего класса (сильно сомневаюсь, что подобные извращения имеют место в практике программирования, но чисто спортивного интереса ради решил помудрить, так что просьба — не бросаться камнями. Раньше времени, во всяком случае). Упрощенно это выглядит так: Вложенные, локальные и анонимные классы - 1

class Outer { // ОБРАМЛЯЮЩИЙ КЛАСС
    static class Inner { // СТАТИЧЕСКИЙ ВЛОЖЕННЫЙ КЛАСС
        int doInnerThings() { // ЛОКАЛЬНЫЙ МЕТОД ВНУТРЕННЕГО КЛАССА
            class LocalInner { // ВНУТРЕННИЙ ЛОКАЛЬНЫЙ КЛАСС
                int doLocalInnerThings() { // МЕТОД ЛОКАЛЬНОГО КЛАССА
                    new Outer(5) {}; // ВНУТРЕННИЙ ЛОКАЛЬНЫЙ АНОНИМНЫЙ КЛАСС
                }
            }
        }
    }
}
Цель: создать переменную в анонимном классе, используя обрамляющий супер-класс, и "перебросить" аргумент этой переменной вплоть до внутреннего класса, присвоив его переменной внутреннего класса, соответственно. Ниже приведен чуть расширенный код, с моими набросками.

class Outer { // ОБРАМЛЯЮЩИЙ КЛАСС
    int outerValue = 0;

    Outer(int a)
    {
        this.outerValue = a*a;
    }

    int getValue() {
        return outerValue;
    }

    static class Inner { // ВНУТРЕННИЙ СТАТИЧЕСКИЙ КЛАСС
        public  int innerValue = doInnerThings();

        int doInnerThings() {
            final int innerValue = 0; // КАК ПЕРЕДАТЬ ЗНАЧЕНИЕ ЭТОЙ ПЕРЕМЕННОЙ ИЗ КЛАССА НИЖЕ?

            class LocalInner { // ЛОКАЛЬНЫЙ КЛАСС
                final public int localInnerValue;

                LocalInner() {
                    localInnerValue = doLocalInnerThings();
                }

                int doLocalInnerThings() {
                    final int[] localInnerAnonValue = {0};

                    new Outer(5) { // АНОНИМНЫЙ КЛАСС
                        @Override
                        int getValue()
                        {
                            localInnerAnonValue[0] = super.getValue();
                            return localInnerAnonValue[0];
                        }
                    };
                    
                    return localInnerAnonValue[0];
                }

                int getlocalInnerValue() {
                    return this.localInnerValue;
                }
            }

            return innerValue;
        }
    }

    public static void main(String[] args) {
        Outer.Inner test = new Outer.Inner();
        System.out.println(test.innerValue);
    }
}
Проблема: метод int doInnerThings()Не могу присвоить переменной этого метода innerValue значение переменной localInnerValue" из локального класса LocalInner. Буду рад помощи! :)
Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Himeg Уровень 15
13 декабря 2016
Тема уже давно уехала в прошлое, но всё равное спасибо за упражнение по ООП.
В вашем примере для того, чтобы значение «localInnerValue» из локального класса «LocalInner» перебросилось до переменной «innerValue» метода doInnerThings(), необходимо создать экземпляр внутреннего класса LocalInner с конструктором LocalInner().
В области метода поля становятся допустимыми только после их объявления. Поэтому, в исходном варианте кода при попытке инициализировать переменную innerValue методом getlocalInnerValue() класса LocalInner будет ошибка компиляции: класс объявляется позднее в области метода. Переменная «innerValue» должна инициализироваться после объявления самого класса:
int doInnerThings() 
{
class LocalInner 
{
...
}
int innerValue = new LocalInner().getlocalInnerValue();
}
Joysi Уровень 41
15 августа 2016
Туманно пытаюсь понять логическую цель, но возможно так
class Outer { // ОБРАМЛЯЮЩИЙ КЛАСС
    int outerValue = 0;

    Outer(int a)
    {
        this.outerValue = a*a;
    }

    int getValue() {
        return outerValue;
    }

    static class Inner { // ВНУТРЕННИЙ СТАТИЧЕСКИЙ КЛАСС
        int innerValue = doInnerThings();

        int doInnerThings() {
            int innerValue = 0; // КАК ПЕРЕДАТЬ ЗНАЧЕНИЕ ЭТОЙ ПЕРЕМЕННОЙ ИЗ КЛАССА НИЖЕ?
            return (innerValue = new LocalInner().getlocalInnerValue());
        }

        class LocalInner { // ЛОКАЛЬНЫЙ КЛАСС
            final int localInnerValue;

            LocalInner() {
                localInnerValue = doLocalInnerThings();
            }

            int doLocalInnerThings() {  // ТУТ МАСЛО МАСЛЯНОЕ
                return (new Outer(5) { // АНОНИМНЫЙ КЛАСС
                    @Override
                    int getValue()
                    {
                        return (Inner.this.innerValue = outerValue);
                    }
                }).getValue();
            }

            int getlocalInnerValue() {
                return this.localInnerValue;
            }
        }

    }

    public static void main(String[] args) {
        Outer.Inner test = new Outer.Inner();
        System.out.println(test.innerValue);
    }
}