Sobes.tech
Middle

Jaké existují typy vnořených tříd?

sobes.tech AI

Odpověď od AI

Vnořené třídy (Nested Classes) v jazyce Java se dělí na dva hlavní typy:

  1. Statické vnořené třídy (Static Nested Classes)

    • Označené modifikátorem static.
    • Chovají se jako běžní statičtí členové třídy-obsahovače.
    • Mohou přistupovat ke statickým členům vnější třídy (i když jsou soukromé).
    • Nemají přímý přístup k nestatickým členům vnější třídy.
    • Jsou vytvářeny bez instance vnější třídy: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();.
  2. Vnořené třídy (Inner Classes)

    Vnořené třídy nejsou označeny static a jsou spojeny s instancí vnější třídy. Dělí se na:

    • Členové třídy (Member Inner Classes)

      • Deklarují se na úrovni člena třídy-obsahovače, ale mimo její metody.
      • Mají přístup ke všem členům vnější třídy, včetně soukromých.
      • Vyžadují instanci vnější třídy k vytvoření vlastní instance: OuterClass outerObject = new OuterClass(); OuterClass.MemberInnerClass innerObject = outerObject.new MemberInnerClass();.
    • Lokální třídy (Local Classes)

      • Vytvářejí se uvnitř metod, konstruktorů nebo inicializačních bloků.
      • Rozsah jejich platnosti je omezen na blok, ve kterém jsou deklarovány.
      • Nelze je deklarovat s přístupovými modifikátory (public, private, protected).
      • Mohou přistupovat k final nebo efektivně final lokálním proměnným vnějšího bloku.
      • Nelze je používat mimo blok, ve kterém jsou definovány.
    • Anonymní třídy (Anonymous Classes)

      • V podstatě jsou to lokální třídy bez jména.
      • Deklarují se a instancují současně.
      • Používají se k implementaci abstraktní třídy nebo rozhraní "za běhu".
      • Stejně jako lokální třídy mají přístup k final nebo efektivně final lokálním proměnným vnějšího bloku.

    Příklad struktury:

class OuterClass {
    private int outerField;
    private static int staticOuterField;

    // Statická vnořená třída
    static class StaticNestedClass {
        void accessOuter() {
            // Může přistupovat ke statickým členům vnější třídy
            int value = staticOuterField;
            // Nemůže přistupovat k nestatickým členům vnější třídy
            // int value2 = outerField; // Chyba kompilace
        }
    }

    // Členová třída (Vnitřní třída)
    class MemberInnerClass {
        void accessOuter() {
            // Může přistupovat ke všem členům vnější třídy
            int value1 = outerField;
            int value2 = staticOuterField;
        }
    }

    void methodWithLocalAndAnonymous() {
        final int localVar = 10; // efektivní final

        // Lokální třída
        class LocalClass {
            void accessOuter() {
                // Může přistupovat ke členům vnější třídy a lokálním final/efektivním final proměnným
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
            }
        }

        LocalClass localObj = new LocalClass();
        localObj.accessOuter();

        // Anonymní třída (implementující rozhraní Runnable)
        Runnable anonymousRunnable = new Runnable() {
            @Override
            public void run() {
                // Může přistupovat ke členům vnější třídy a lokálním final/efektivním final proměnným
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
                System.out.println("Running with local variable: " + localValue);
            }
        };

        anonymousRunnable.run();
    }
}