belső osztályok a java-ban

belső osztály jelentése
ahogy a neve is mondja, egy másik osztályon belüli osztályt belső osztálynak nevezünk.
a belső osztályok különleges kapcsolatban állnak a tartalmazó osztályával, mivel hozzáférhetnek a külső osztály összes tagjához(még a private tagokhoz is).
ez azért van, mert egy belső osztály is tagja a külső osztálynak, mint más mezők és módszerek.
mivel egy belső osztály egy másik osztályon belüli osztály, beágyazott osztálynak is nevezhető.
belső osztályok típusai
egy belső osztály a következő típusokból állhat.

  1. normál vagy szabályos vagy beágyazott belső osztály(általában csak belső osztálynak nevezik)
  2. módszer helyi belső osztály.
  3. névtelen belső osztály.
  4. statikus beágyazott osztály

1. Beágyazott belső osztály
ez a szakasz egy belső osztály minden részletét bemutatja. Az egyszerűség kedvéért vegyük figyelembe a következő osztályokat

class Outer { private String outerField = "Outer"; class Inner { private String innerField = "Inner"; }}

itt a külső a külső osztály, a belső pedig a belső osztály, amely a külső belsejében található.

belső osztály objektumának létrehozása
egy belső osztály egy másik osztályon belül van. Az osztályt külső osztálynak nevezzük. Így egy belső osztály nem létezhet külső osztály nélkül, és ugyanez vonatkozik az objektumára(vagy példányára).
egy belső osztályú objektum nem létezhet külső osztályú objektum nélkül.
ez azt jelenti, hogy a belső osztály példányának létrehozásához rendelkeznie kell egy külső osztály példányával.
így a belső osztály tárgya az alábbi módszerrel hozható létre.

// first, create object of outer classOuter outerObject = new Outer();// create object of inner classInner innerObject = outerObject.new Inner();

amint a példából kitűnik, belső osztályú objektum létrehozásához külső osztályú objektumra van szükség.
van egy rövid kézi módszer a belső osztály objektum létrehozására is.

Inner innerObject = new Outer().new Inner();

Ez a módszer külső osztályobjektumot is igényel.
csak Remember….An a belső osztály objektuma nem hozható létre annak tartalma (vagy külső osztálya) nélkül.

belső osztály objektum létrehozása a külső osztályon belül
az előző példa feltételezi, hogy a belső osztályt a külső osztályon kívülről példányosítja.
de a legtöbb esetben a belső osztály objektumára csak a külső osztályon belül van szükség, mivel a külső osztály a belső osztályt használja.
tehát hogyan hozhatunk létre egy belső osztályú tárgyat a külső osztály belsejéből?
fontolja meg az alábbi módosított mintaosztályt.

class Outer { private String outerField = "Outer"; public void createInnerClassObject() { // create an object of inner class Inner innerObject = new Inner(); } class Inner { private String innerField = "Outer"; }}

vegye figyelembe a Inner innerObject = new Inner(); Sort.
korábban kijelentették, hogy egy belső osztályobjektum nem hozható létre külső osztályobjektum nélkül, de a fenti kódrészlet megteszi. Összezavarodtam !!!!
a fenti szintaxis érvényes, mert a külső osztály metódusába van írva.
amikor ez a kód fut, már van egy külső osztály példánya, amely a metódust futtatja.

mindig emlékezzen arra, hogy a belső osztály objektumának létrehozásához(vagy eléréséhez) a külső osztály példányának kell lennie.

összefoglalni,

  1. ha egy belső osztályú objektum a külső osztályból jön létre, akkor közvetlenül Inner innerObject = new Inner();néven hozható létre.
  2. ha egy belső osztályú objektumot a külső osztályon kívülről hozunk létre, akkor azt Inner innerObject = new Outer().new Inner();néven kell létrehozni.

amikor külső és belső osztályú objektumokat nyomtatnak, a következő kimenet jön létre:

külső osztály példány: külső@659e0bfd
belső osztály példány : Külső$Inner@2a139a55

hivatkozás külső osztály példány, mezők és módszerek belső osztály
egy belső osztály is tagja a tartalmazó osztály, mint más mezők és módszerek.
így a külső osztály többi mezőjéhez és metódusához ugyanúgy férhet hozzá, mint más mezők és metódusok egymáshoz, közvetlenül.
ez akkor érvényes, ha külső osztálymezőket és metódusokat érünk el a belső osztályból.

de a külső osztály példányának hivatkozásakor különbség van. Az osztály aktuális példányára való hivatkozáshoz a this kulcsszót használjuk.
belső osztály esetén a this belső osztály használata a belső osztály aktuális példányára utal, nem pedig a külső osztályára.
a külső osztály példányának a belső osztályból való hivatkozásához hozzá kell adnunk az osztály nevét a this kulcsszóhoz.

ezért a külső osztály példányára a belső osztályból való hivatkozáshoz használja a Outer.this szintaxist.
lásd az alábbi példát a megértéshez.

class Outer { private String outerField = "Outer"; public void createInnerClassObject() { // create an object of inner class Inner innerObject = new Inner(); } class Inner { private String innerField = "Outer"; public innerClassMethod() { // access outer class field System.out.println("Outer field : " + outerField); // access inner class instance System.out.println("Inner instance : " + this); // access outer class instance System.out.println("Outer instance : " + Outer.this); } }}

kimenet

külső mező: külső
belső példány:
külső példány :

2. Method Local Inner Class
ahogy a neve is sugallja,a metóduson belül definiált osztály Method Local Inner Class.
igen, lehetséges.
megadhat egy osztályt egy metóduson belül az alábbiak szerint.

// outer classclass Outer { // outer class method public void createClass() { // class inside a method class Inner { // inner class method public void innerMethod() { System.out.println("Method local inner class"); } } // inner class ends } // method ends}

fenti kód egy osztály külső tartalmazó módszer.
ez a módszer meghatároz egy osztályt, amely a metódus testén belül van, ezért metódus helyi belső osztálynak nevezzük.
figyeljük meg, hogy a belső osztálynak is van saját módszerdefiníciója.

metódus példányosítása helyi belső osztály
az előző kód deklarálja a metódus helyi belső osztályát, de nem hoz létre belső osztály objektumot.
most felmerül a kérdés, hogyan lehet létrehozni egy objektum módszer helyi belső osztály.
mivel egy metódus helyi belső osztályát egy metóduson belül definiáljuk, csak az adott metóduson belül látható, és objektuma is csak ezen metóduson belül hozható létre.
a kód alatt létrehoz egy objektum metódus helyi belső osztály és meghívja a metódus.

// outer classpublic class Outer { // outer class method public void createClass() { // class inside a method class Inner { // inner class method public void innerMethod() { System.out.println("Method local inner class method called"); } } // inner class ends // create inner class object Inner innerObject = new Inner(); // call inner class method innerObject.innerMethod(); } // outer class method ends // Main method public static void main(String args) { // create object of outer class Outer outerObject = new Outer(); // call outer class method outerObject.createClass(); }}

a fenti kód végrehajtásakor a következő a kimenet

metódus helyi belső osztály metódus, az úgynevezett

Ez azt mutatja, hogy amikor külső osztály metódust hívnak, létrehoz egy belső osztály objektumot, és meghívja a belső osztály metódust.

method Local Inner Class : Points to Remember
utasítás, amely létrehozza a method local inner class objektumát, az osztály testén kívül kell írni.
így a Inner innerObject = new Inner(); sornak a helyi osztály vége után kell jönnie.

  1. egy metódus helyi belső osztálya csak azon a metóduson belül példányosítható, amelyben deklarálták.
    ennek van értelme, mivel egy metódusosztály csak a metóduson belül látható, így objektuma csak az adott metóduson belül hozható létre.
  2. a módszer helyi belső osztály nem férhet hozzá a helyi változók a módszer, amelyben azt nyilvánították.
    ha hozzá kell férnie hozzájuk, akkor azokat final jelöléssel kell ellátni.
    ez a java 8 előtt alkalmazható.
  3. nem férhet hozzá egy metódus helyi változóhoz egy metódus helyi belső osztályán belül, majd újra hozzárendelheti. Ez fordító hiba lesz.
    ez a java 8-ból alkalmazható, mivel a java 8 előtti verziók még a method local változót sem teszik lehetővé a belső osztályon belül.
  4. a helyi belső osztály metódusai elérhetik annak az osztálynak a mezőit és más metódusait, amelyhez a belső osztályt tartalmazó metódus tartozik.
  5. a helyi belső osztály metódusai csak akkor férhetnek hozzá annak az osztálynak a static mezőjéhez és egyéb staticmetódusaihoz, amelyhez a belső osztályt tartalmazó metódus tartozik, ha a belső osztályt tartalmazó metódus static.

3. Névtelen belső osztályok
névtelen azt jelenti, akinek a neve nem ismert. A java kontextusában anonim osztály az, amelynek nincs neve.
a névtelen osztály kifejezés csak a belső osztályokra vonatkozik, mivel a külső osztályoknak nevet kell adniuk.
az anonim osztály belső osztály, mert mindig egy másik osztályon belül lesz meghatározva.

Az anonim osztály típusai a java-ban
valójában az anonim osztály egy már létező osztály vagy interfész megvalósítása, amely valahol máshol van írva, de szükség szerint újra meg van határozva egy másik osztályon belül.
ez zavarónak tűnhet, de a következő példák tisztázzák a fogalmat.

annak alapján, hogy az anonim osztály egy osztály vagy interfész megvalósítása, az alábbi két kategóriába tartozhat

A. Egy osztály alosztálya
kezdjük először egy példával

// Already existing classclass Website {public void printName() {System.out.println("No website till now");}}class SearchEngine { // Notice the syntax Website w = new WebSite() { public void printName() { System.out.println("Website is codippa.com"); } };}

a fenti példában van egy weboldal nevű osztály, amely már létrejött.
egy másik osztály SearchEngine újradefiniálja ezt az osztályt, végrehajtja a metódusát, és hozzárendeli egy referencia változóhoz, amely ugyanolyan típusú, mint a tényleges osztály.
az újonnan megvalósított metódust is meg lehet hívni ezzel a referencia változóval.

ne feledje, hogy az újonnan megvalósított névtelen osztály a tényleges osztály alosztálya.
a polimorfizmust követi, és az objektum bárhol átadható, ahol a Website osztály tárgya várható.
nézze át az alábbi példát illusztrációként.

class Website { public void printName() { System.out.println("No website till now"); }}class SearchEngine { // Notice the syntax Website w = new WebSite() { public void printName() { System.out.println("Website is codippa.com"); } }; // Expects an instance of Website class public void getWebsite(Website web) { // call the method of Website class web.printName(); } // Main method public static void main(String args) { // create an object of this class SearchEngine obj = new SearchEngine(); // call its method and pass instance of Website class obj.getWebsite(obj.w); }}

a Website osztály implementációjának előzetes meghatározása helyett szükség esetén definiálható, azaz a getWebsite metódus meghívása közben.
így a fő módszer módosítható

public static void main(String args) { SearchEngine obj = new SearchEngine(); // Notice the implementation of Website class as argument obj.getWebsite(new Website() { public void print() { System.out.println("Dynamic implementation"); } });}

a fenti megvalósítás nincs hozzárendelve semmilyen referencia változóhoz, nincs neve, ezért a név névtelen.

nem szükséges, hogy mindkét osztály ugyanabban a fájlban vagy csomagban legyen. Ezek bárhol elhelyezhetők egymáshoz képest.

B. Az interfész megvalósítója
anonim osztály meghatározható egy interfész megvalósítójaként is.
ebben az esetben meghatározza az interfészen deklarált módszerek implementációját, és bárhol átadható, ahol az interfész tárgya várható.
Lásd az alábbi példát, hogy egyértelmű legyen.

interface WebInterface { // interface method declaration public void print();}class SearchEngine { // Notice the syntax WebInterface w = new WebInterface() { // Interface method implementation public void printName() { System.out.println("Website is codippa.com"); } }; // Expects an instance of WebInterface interface public void getWebsite(WebInterface web) { // call the method of WebInterface web.printName(); } // Main method public static void main(String args) { // create an object of this class SearchEngine obj = new SearchEngine(); // call its method and pass instance of WebInterface obj.getWebsite(obj.w); }}

mint korábban, az interfész anonim osztályként történő megvalósítása szükség esetén létrehozható az alábbiak szerint.

public static void main(String args) { SearchEngine obj = new SearchEngine(); // Notice the implementation of WebInterface as argument obj.getWebsite(new WebInterface() { public void print() { System.out.println("Dynamic implementation"); } });}
figyelje meg a new kulcsszó használatát az interfész neve előtt. Anonymous osztály az egyetlen hely, ahol ez lehetséges.

polimorfizmus anonim osztályokban
mint korábban említettük, az anonim osztályok polimorfizmust követnek.
mivel ezek alosztályok, a polimorfizmust kell követniük. Ez a szakasz részletezi, hogyan.
Tekintsük az alábbi osztályt.

class Metal { public void printThickness() { System.out.println("Thick enough"); }}class MetalDriver { // Anonymous class definition Metal metal = new Metal() { public void printThickness() { System.out.println("Thick enough"); } // new method public boolean hasLustre() { return false; } }; public void printMetalDetail(Metal m) { // call method present in actual class definition. No problem!!! m.printThickness(); // call newly defined method in Anonymous class. Compiler Error!!! m.hasLustre(); }}

a fenti kód egy fémosztályt határoz meg egyetlen módszerrel.
ezt az osztályt ismét anonim módon hajtják végre egy másik metaldriver osztályban, ahol egy új metódust adnak a definíciójához, amely nincs jelen a tényleges osztályban.

Most, amikor ezt az új módszert hívják, a fordító hibát panaszkodik

a módszer hasLustre() nincs meghatározva a Metal típushoz.

Ez azért van, mert az anonymous osztály egy alosztály, míg a hivatkozás tényleges osztály(amely a szülő).
a fordító nem találta az új módszert a szülő osztályban, és hibát jelez.

így a hiba két tényt állapít meg:
(i) az anonim osztály a tényleges osztály alosztálya, és
(ii) az anonim osztálydefiníciók a polimorfizmust követik.

anonim osztály használata
tegyük fel, hogy meg kell hívnia egy metódust, amely olyan típusú argumentumot vesz fel, amely interfész.
ez az interfész valamilyen külső könyvtárhoz tartozik, és nincs olyan osztály, amely megvalósítaná ezt az interfészt.
hogyan fogja hívni ezt a módszert. Ha átadja a null értéket, akkor fennáll a futási idő kivételének veszélye.
névtelen osztály a mentéshez.
most létrehozhat egy anonim osztályt, amely megvalósítja ezt a felületet, és átadja azt a metódusnak, amely a metódusok megvalósítását biztosítja az Ön igényeinek megfelelően.
példa következik.

// Interface from external Libraryinterface External { public void interfaceMethod();}class CalledClass { // Method to called. Takes an argument of interface type public void toBeCalled(External e) { e.interfaceMethod(); }}

a fenti kódnak van egy interfésze egyetlen metódussal és egy osztályával, amelynek metódusát meg kell hívnia a kódjából.

ennek az osztálynak a metódusa interface típusú argumentumot vesz fel, de nincs olyan osztály, amely megvalósítaná ezt az interfészt.
ha átadja az nullértéket a metódus argumentumnak, akkor azonnal java.lang.NullPointerException – t dob.
nézze meg, hogyan hívhatja ezt a módszert az Anonymous osztály használatával.

class CallingClass { // Main method public static void main(String args) { CalledClass obj = new CalledClass(); // call method using Anonymous class obj.toBeCalled(new External() { public void interfaceMethod() { // your code } }); }}

figyelje meg a névtelen interfész implementáció használatát a módszer meghívására.
ez a névtelen osztályok legnagyobb előnye.
4. Statikus beágyazott osztály
a statikus osztály, amelyet egy másik osztályon belül definiálnak, statikus beágyazott osztály. Úgy van meghatározva, mint egy normál osztály, amelyet statikus kulcsszó előz meg.
ne feledje, hogy nincs statikus osztály, a statikus beágyazott osztály csak a külső osztályának statikus tagja.
mivel statikus tag, a következő statikus beágyazott osztályra vonatkozik.

  1. a külső osztály közvetlenül hozzáférhet a példány nélkül.
  2. csak külső osztályának statikus tagjaihoz férhet hozzá, példányváltozóihoz vagy metódusaihoz nem.

statikus beágyazott osztály példa

public class Outer { // static nested class static class Inner { public void innerMethod() { System.out.println("Method of static nested class"); } } public void outerMethod() { System.out.println("Method of outer class"); } public static void main(String args) { // access inner class directly Inner inner = new Inner(); // call nested class method inner.innerMethod(); }}

a fenti példából látható, hogy a statikus beágyazott osztály eléréséhez nincs szükség külső osztály példányára, és közvetlenül elérhető.
vegye figyelembe, hogy a statikus beágyazott osztály objektumai nem férhetnek hozzá a külső osztály nem statikus tagjaihoz. A fenti példában a beágyazott osztálypéldány nem hívhatja meg a külső osztály outerMethod értékét.

Let ‘ s csípés a

  1. amikor egy osztály tartalmazó belső osztály össze, akkor 2 osztály fájlok keletkeznek :
    egy külső osztály és egy belső osztály.
    Példa, Külső.osztály és külső$belső.osztály a külső osztály külső, illetve a belső osztály belső osztályához..
  2. a belső osztály Osztályfájlja nem hajtható végre közvetlenül a java paranccsal.
  3. egy normál belső osztálynak nem lehet static adattagja vagy metódusa.
  4. egy belső osztálynak lehet konstruktora.
  5. egy metódus helyi osztálya csak azon a metóduson belül példányosítható, amelyben meg van határozva.
  6. a static metódusban definiált metódus helyi osztály csak a körülzáró osztály static tagjaihoz férhet hozzá.
  7. egy anonim osztály, amely interfészt valósít meg, csak egy interfészt valósíthat meg, szemben a normál osztályokkal, amelyek sokakat megvalósíthatnak.
  8. egy anonim osztály nem képes kiterjeszteni egy osztályt és implementálni egy interfészt egy időben, amit a normál osztályok képesek.
  9. a névtelen osztálydefiníciók}-vel végződnek; (vegye figyelembe a pontosvesszőt).
  10. anonim osztályok, amelyeket argumentumként definiálnak egy metódus meghívása közben,} – vel végződnek; (figyelje meg a pontosvesszőt).
  11. nem lehet hívni egy módszert névtelen osztály referencia, amely nincs jelen a tényleges osztály.
  12. a static előtti belső osztályt beágyazott osztálynak nevezzük, Nem Belső osztálynak.

Leave a Reply