Правила за обхват на Java и вътрешни класове

Всички луди правила за обхват на Java замайват главата ми и глупостите с public static void не помагат. Досега всички езици за програмиране, които съм използвал или лексикален обхват, или някакво негово приближение без никакви модификатори за достъп, т.е. вътрешните неща улавят външните неща и имат достъп до външните неща, стига вътрешните неща да съществуват.

И така, как да осмисля правилата за обхват за вътрешни класове в Java? Получават ли достъп до променливи, декларирани във външния клас, или има някакви странни крайни случаи, за които трябва да се тревожа, поради всички публични статични частни неща, които се носят наоколо?


person David K.    schedule 31.01.2011    source източник
comment
Погледнете референтната карта на тази публикация ( в долната част на статията), който обобщава правилата за обхват.   -  person Aravind Yarram    schedule 31.01.2011
comment
Моля (1) смекчете тона и (2) изяснете въпроса си. „Лудите правила за обхват на Java“, за които питате, са идентични с „лексикалното определяне на обхвата“, както в C++. Ще трябва да обясните какво имате предвид под глупостите „public static void“: това е друга функция, която също съществува в C++. И „обществените статични частни“ неща, които се носят наоколо, не съществуват: това е просто противоречие в термините.   -  person user207421    schedule 31.01.2011
comment
Съвсем сигурен съм, че OP идва от основа на скриптов език с истински лексикален обхват (напр. JavaScript, Ruby) и по-малко акцент върху модификаторните ключови думи навсякъде. Просто казвам.   -  person ide    schedule 31.01.2011
comment
@EJP: Въпросът е доста ясен. Модификаторите за достъп взаимодействат с обхвата и не е ясно как модификаторите за достъп променят лексикалния обхват за екземпляри и вътрешни класове.   -  person David K.    schedule 31.01.2011
comment
@davidk01: Не съм съгласен. Той изобщо не споменава модификатори за достъп, а само правила за обхват. И „луд“, „глупости“ и т.н. също не са мили.   -  person user207421    schedule 31.01.2011
comment
@EJP: Мисля, че „public static void“, „public static private“ се квалифицира като споменаване на модификатори за достъп. Всички квалификатори наистина са глупости, защото всеки друг език за програмиране успява да се справи без тях и всички церемониални заклинания, които Java изисква. Както и да е, не съм тук, за да споря с вас за недостатъците на Java.   -  person David K.    schedule 31.01.2011
comment
@davidk01: Това също се квалифицира като публикуване на глупости.   -  person user207421    schedule 31.01.2011
comment
Въпросът ви е ясен и настроението ви е човешко. Ние не сме машини и не трябва да се държим като такива.   -  person Markus Siebeneicher    schedule 13.11.2014


Отговори (6)


Статичните вложени класове1 са точно като външните класове, с изключение на това, че имат достъп до всички членове на външния клас, независимо от квалификатора за достъп. Те съществуват отделно от всеки екземпляр на външния клас, така че се нуждаят от препратка към екземпляр, за да имат достъп до променливи на екземпляр или нестатични методи на външния клас.

Нестатичните вложени класове (наречени вътрешни класове) възникват само в контекста на екземпляр на външния клас. Когато са конструирани, те имат автоматично генерирано второ поле this, до което можете да получите достъп от вътрешния клас, като използвате синтаксиса Outer.this. Всеки екземпляр на вътрешния клас е ограден от един екземпляр на външния клас. Отново, всички привилегии за достъп на статичните вложени класове се отнасят за вътрешните класове. Но тъй като те вече имат наличен екземпляр на външния клас, те могат автоматично да имат достъп до променливи на екземпляр и методи на външния клас.

За хубава (и много подробна) дискусия на вътрешните класове и спецификаторите за достъп можете да прочетете Спецификация на вътрешния клас. Той описва, наред с други неща, как вложен клас получава достъп до private члена на своя външен клас(ове). По-щадящо четене е урокът за вложени класове.

Извън темата настрана: Да предположим, че имате следната структура на класа:

public class O {
    public O() { ... }

    public class I { // an inner class
        public I() { ... }
        ...
    }
    ...
}

и сте създали екземпляр на O:

O outer = new O();

Сега да предположим, че искате да създадете екземпляр на O.I. не можете просто да използвате new O.I(), защото новото копие на I трябва да бъде оградено от конкретно копие на O. За това Java предоставя следния синтаксис:

O.I inner = outer.new O.I();

Тогава inner ще има второто си поле this, настроено да препраща към outer.

Имайте предвид, че този синтаксис на "квалифициран new оператор" се използва само за вътрешни класове; би било ненужно (всъщност, грешка), ако I беше static вложен клас.

1 Често ще срещнете израза „статичен вътрешен клас“ (включително, смущаващо, в по-ранна версия на този отговор). Това е неправилна терминология. В Java „вътрешните класове“ са специално не-static вложени класове.

person Ted Hopp    schedule 31.01.2011
comment
Този втори параграф е ключовата разлика между статични и вътрешни класове на екземпляри. - person ide; 31.01.2011
comment
Това е съвсем ясно. Така че, ако ви разбрах правилно, всеки вид променлива, декларирана във външния клас, независимо от какъвто и да е вид модификатор за достъп, е достъпна от нестатичен вътрешен клас. Така че всички статични и частни променливи и методи във външните класове са достъпни от вътрешния клас. - person David K.; 31.01.2011
comment
Това е всичко. Ако производителността е критична, имайте предвид, че има леко наказание във времето и паметта за вътрешен клас за достъп до защитени или частни членове на външния клас (и обратно). Веднъж компилирани, вътрешните класове (статични или не) се третират в байтовия код като отделни класове. По този начин компилаторът трябва да създаде функции за достъп, така че байт кодът да се подчинява на правилата за достъп. - person Ted Hopp; 31.01.2011

Трябва да разграничите:

  • Статичните вътрешни класове имат достъп до всички статични членове извън тяхната декларация.
  • Вътрешните класове на екземпляра имат достъп до всички членове на класа извън тяхната декларация И до final полета във функцията, в която са декларирани.

Имайте предвид, че нестатичният вътрешен клас също има скрита променлива с екземпляра на външния клас за достъп до членовете там. И че всички референтни крайни полета (следователно те трябва да са окончателни) се копират във вътрешния клас в други скрити членски променливи, когато вътрешният клас се инстанцира.

Пример:

public void doStuff(final int a, int b) {
    final int c; // Can be referenced
    int d;       // Cannot be referenced, not final

    executer.execute( new Runnable() {
        public void run() {
            System.out.println("a: "+a+"  c: "+c);
        }
    }

    b++; // Not final, not referencable
    System.out.println(b);
}
person Daniel    schedule 31.01.2011

Не знам дали помага, но от уроци за Java:

Статични вложени класове

Както при методите и променливите на класа, статичен вложен клас е свързан с неговия външен клас. И подобно на статичните методи на класа, статичен вложен клас не може да препраща директно към променливи на екземпляр или методи, дефинирани в неговия обхващащ клас — той може да ги използва само чрез препратка към обект. Забележка: Статичният вложен клас взаимодейства с членовете на екземпляра на своя външен клас (и други класове) точно както всеки друг клас от най-високо ниво. Всъщност статичен вложен клас е поведенчески клас от най-високо ниво, който е бил вложен в друг клас от най-високо ниво за удобство на опаковането.

Вътрешни класове [Нестатичен вложен клас?]

Както при методите и променливите на екземпляра, вътрешният клас е свързан с екземпляр на обграждащия го клас и има директен достъп до методите и полетата на този обект. Освен това, тъй като вътрешен клас е свързан с екземпляр, той не може сам да дефинира никакви статични членове.

Трябва да проверите урока за Java за вложени класове.

person Andre85    schedule 31.01.2011

Правила на вътрешните класове в Java

  1. В Java е възможно да се дефинира клас в друг клас, такива класове се наричат ​​вложени класове или вътрешен клас.
  2. Има 3 вида вътрешни класове Екземпляр Вътрешен клас, статичен вътрешен клас и анонимен вътрешен клас
  3. Ако вътрешният клас е деклариран като вътрешен клас на екземпляр, тогава той има достъп до всички членове на външния обхващащ клас, включително частни членове
  4. Ако вътрешният клас е деклариран като статичен, тогава той може да има достъп само до статичните членове на външния клас (включително частните статични членове). Но НЕ може да има достъп до членовете на екземпляра
  5. Помислете, че има променлива x, която е дефинирана както във външния клас, така и във вътрешните класове на екземпляра, тогава общата форма за достъп до променливата от вътрешния клас е this.x за вътрешния x и OuterClassname.this.x за външния x.
  6. Можете също да дефинирате вътрешен клас във всеки метод или друг блок
  7. Общата форма за инстанциране на вътрешния клас извън външния клас е Outer.Inner ob = new Outer.new Inner();
  8. Общата форма за инстанциране на вътрешния клас извън външния клас е (ако вътрешният клас е деклариран като статичен) Outer.Inner ob = new Outer.Inner();
  9. Вътрешните класове могат да бъдат декларирани с всяка от ключовите думи на модификатора на достъпа
  10. Ако вътрешният клас е деклариран като частен, тогава той НЕ може да бъде създаден извън външния клас. Също така в този случай НЕ можете да получите достъп до членовете на вътрешния клас извън външния клас, дори да имате препратка към обект и дори ако членовете на частния вътрешен клас са декларирани като публични.
  11. Ако вътрешният клас е деклариран като вътрешен клас на екземпляр, тогава той може също така да има достъп до членовете на суперкласа на външния клас чрез общата инструкция Outer.super.variable; Outer.super.method(params);
person Vipul Verma    schedule 12.04.2018

Правила за вътрешен клас

  1. Външен клас, достъпен от вътрешен клас
  2. Вътрешният клас не може да бъде достъпен от външен клас
  3. Членовете на вътрешния клас са използвали само методите, а членовете в класа имат достъп само до пълната информация
person user2701769    schedule 21.08.2013

Вътрешни класове с обхват на метод: - Имат достъп само до крайните членове на външния клас.

person Shikhar    schedule 07.08.2015