Sobes.tech
Middle

Räägi siseklassidest ja millal neid kasutatakse.

sobes.tech AI

Vastus AI-lt

Java-sises klassid (Nested Classes) on klassid, mis on määratletud teise klassi sees. Nad jagunevad kaheks tüübiks: staatilised (Static Nested Classes) ja sisemised klassid (Inner Classes):

Staatilised sisemised klassid

  • Määratletud static modifikaatoriga.
  • Neil on juurdepääs ainult välise klassi staatilistele liikmetele (isegi kui need on varjatud).
  • Neil ei ole juurdepääsu välise klassi mitte-staatilistele liikmetele.
  • Staatilise sisemise klassi eksemplari loomine ei nõua välise klassi eksemplari:
    // Välise klass
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Staatiline sisemine klass
        static class StaticNested {
            void accessOuter() {
                // Juurdepääs välise klassi staatilisele väljale
                System.out.println(Outer.outerStaticField);
                // Juurdepääs välise klassi mitte-staatilisele väljale ei ole võimalik
                // System.out.println(outerInstanceField); // Kompilatsiooni viga
            }
        }
    }
    
    // Staatilise sisemise klassi kasutamine
    class Main {
        public static void main(String[] args) {
            Outer.StaticNested nestedObject = new Outer.StaticNested();
            nestedObject.accessOuter();
        }
    }
    

Sisemised klassid

  • Määratletud ilma static modifikaatorita.
  • Neil on täielik juurdepääs kõigile välise klassi liikmetele (staatilised ja mitte-staatilised, isegi kui need on varjatud).
  • Sisemise klassi eksemplar ei saa eksisteerida ilma välise klassi eksemplarita.
  • Sisemise klassi eksemplari loomiseks on vaja välise klassi eksemplari:
    // Välise klass
    class Outer {
        static int outerStaticField;
        int outerInstanceField;
    
        // Sisemine klass
        class Inner {
            void accessOuter() {
                // Juurdepääs välise klassi staatilisele väljale
                System.out.println(Outer.outerStaticField);
                // Juurdepääs välise klassi mitte-staatilisele väljale
                System.out.println(outerInstanceField);
            }
        }
    }
    
    // Sisemise klassi kasutamine
    class Main {
        public static void main(String[] args) {
            Outer outerObject = new Outer();
            Outer.Inner innerObject = outerObject.new Inner();
            innerObject.accessOuter();
        }
    }
    

Sisemed klassid jagunevad:

  • Otse sisemised klassid: määratletud välise klassi kehas.
  • Piirkondlikud sisemised klassid: määratletud meetodite, konstruktorite või initsialiseerimisblokkide sees ning nähtavad ainult selles blokis.
    class Outer {
        void display() {
            class LocalInner { // Piirkondlik sisemine klass
                void message() {
                    System.out.println("Piirkondlik sisemine klass");
                }
            }
            LocalInner obj = new LocalInner();
            obj.message();
        }
    }
    
  • Anonüümse sisemise klassid: nimeta klassid, mida kasutatakse eksemplari loomisel või liideste (interface) realiseerimisel ning nende realiseerimine toimub kohe. Sageli kasutatakse sündmuste kuulajate (event listeners) puhul:
    interface Greeting {
        void sayHello();
    }
    
    class Main {
        public static void main(String[] args) {
            Greeting greeting = new Greeting() { // Anonüümne sisemine klass
                @Override
                public void sayHello() {
                    System.out.println("Tere!");
                }
            };
            greeting.sayHello();
        }
    }
    

Millal kasutatakse sisemisi klasse:

  • Loogiline grupeerimine: Kui klass on ainult teise klassi osa ja selle grupeerimine koos on mõttekas. See parandab koodi loetavust ja hooldatavust.
  • Inkapulatsioon: Sisemised klassid võivad pääseda välise klassi liikmetele, pakkudes tihedamat seost ja võimalust varjata realiseerimise detaile.
  • Parema koodi lugemine: Kui väike, lihtne klass kasutatakse ainult ühes kohas, võib selle sisestamine muuta koodi puhtamaks.
  • Resursside tõhus kasutamine: Sisemised klassid pääsevad välise klassi liikmetele ilma nende selge edastamiseta, mis võib koodi lihtsustada. Näiteks iteratoride realiseerimine.
  • Liideste või klasside laiendamine kontekstis: Anonüümseid sisemisi klasse kasutatakse sageli liideste või abstraktsete klasside kompaktseks realiseerimiseks "kohapeal".
  • Realiseerimise varjamine: Klasside varjamine teise klassi sees, muutes selle väljast nähtamatuks.

Võrdlus staatiliste ja sisemiste klasside vahel:

Parameeter Staatiline sisemine klass Sisemine klass
static modifikator Jah Ei
Juurdepääs välise klassi liikmetele Ainult statilised (ka varjatud) Kõik liikmed (staatilised ja mitte-staatilised, varjatud)
Vajalik välise klassi eksemplar selle loomiseks Ei Jah
Seos välise klassi eksemplariga Ei Jah

Valik staatilise sisemise ja sisemise klassi vahel sõltub sellest, kas sisemine klass vajab juurdepääsu mitte-staatilistele välise klassi liikmetele. Kui vajab, kasutage sisemist klassi. Kui mitte, siis sobib paremini staatiline sisemine klass, kuna see ei ole seotud välise klassi eksemplariga ja võib olla tõhusam.