indre klasser i java

indre klasse betydning
som navnet siger, kaldes en klasse inde i en anden klasse en indre klasse.
indre klasser deler et særligt forhold til dets indeholdende klasse, idet den har adgang til alle medlemmer af ydre klasse(selv private dem).
dette skyldes, at en indre klasse også er medlem af ydre klasse ligesom andre felter og metoder.
da en indre klasse er en klasse inde i en anden klasse, kan den også betegnes som en indlejret klasse.
typer af indre klasser
en indre klasse kan være af følgende typer.

  1. Normal eller regelmæssig eller indlejret indre klasse(normalt benævnt bare indre klasse)
  2. metode lokal indre klasse.
  3. anonym indre klasse.
  4. statisk indlejret klasse

1. Indlejret indre klasse
dette afsnit vil grave i alle detaljerne i en indre klasse. For enkelhed, overveje følgende klasser

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

her ydre er den ydre klasse og indre er den indre klasse, som er indeholdt inde ydre.

oprettelse af objekt for Indre klasse
en indre klasse er inde i en anden klasse. Indeholder klasse kaldes ydre klasse. Således kan en indre klasse ikke eksistere uden ydre klasse, og det samme gælder for dens objekt(eller forekomst).
et objekt af indre klasse kan ikke eksistere uden et objekt af ydre klasse.
dette betyder, at for at oprette en forekomst af indre klasse, skal du have en forekomst af ydre klasse.
således kan objekt af indre klasse oprettes ved nedenstående givne metode.

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

som det fremgår af eksemplet, for at skabe et objekt af indre klasse, er et objekt af ydre klasse nødvendigt.
der er også en korthåndsmetode til oprettelse af indre klasseobjekt.

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

denne metode kræver også ydre klasseobjekt.
lige Remember….An objekt af indre klasse kan ikke oprettes uden et objekt af dets indeholdende (eller ydre klasse).

oprettelse af indre klasseobjekt i ydre klasse
forrige eksempel forudsætter, at du instantierer indre klasse fra et sted uden for den ydre klasse.
men i de fleste tilfælde kræves der kun et objekt af indre klasse inde i den ydre klasse, da ydre klasse gør brug af indre klasse.
så hvordan skaber vi et objekt af indre klasse fra indre ydre klasse?
overvej ændret prøveklasse nedenfor.

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"; }}

Læg mærke til linjen Inner innerObject = new Inner();.
tidligere blev det sagt, at et indre klasseobjekt ikke kan oprettes uden et objekt af ydre klasse, men ovenstående kodestykke gør det. Forvirret !!!!
ovenfor syntaks er gyldig, fordi det er skrevet inde i en metode af ydre klasse.
når denne kode udføres, er der allerede en forekomst af ydre klasse til stede, som kører metoden.

husk altid, for at skabe(eller få adgang til) et objekt af indre klasse, skal der være en forekomst af ydre klasse.

for at opsummere,

  1. når et objekt af indre klasse oprettes indefra ydre klasse, kan det oprettes direkte som Inner innerObject = new Inner();.
  2. når et objekt af indre klasse oprettes uden for ydre klasse, skal det oprettes som Inner innerObject = new Outer().new Inner();.

når objekter af ydre og indre klasse udskrives, er følgende output genereret:

ydre klasse instans: ydre@659e0bfd
indre klasse instans : Outer $ Inner@2a139a55

henvisning til Outer Class-forekomst, felter og metoder fra Inner class
en indre klasse er også medlem af dens indeholdende klasse som andre felter og metoder.
således kan den få adgang til andre felter og metoder i ydre klasse på samme måde som andre felter og metoder får adgang til hinanden direkte.
dette gælder ved adgang til ydre klassefelter og metoder fra indre klasse.

Men når der henvises til forekomsten af ydre klasse, er der en forskel. For at henvise til den aktuelle forekomst af en klasse anvendes this søgeord.
i tilfælde af indre klasse henviser brug af this indvendig indre klasse til den aktuelle forekomst af indre klasse og ikke dens ydre klasse.
for at referere forekomst af ydre klasse fra indre klasse, er vi nødt til at tilføje klasse navn til this søgeord.

for at henvise til forekomst af ydre klasse fra indre klasse skal du bruge Outer.this syntaks.
se nedenstående eksempel for forståelse.

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); } }}

udgang

ydre felt : ydre
indre forekomst:
ydre forekomst :

2. Metode lokal indre klasse
som navnet antyder, er en klasse defineret inde i en metode en metode lokal indre klasse.
ja, det er muligt.
du kan definere en klasse inde i en metode som vist nedenfor.

// 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}

ovenstående kode har en klasse ydre indeholdende en metode.
denne metode definerer en klasse, der er inde i metodekroppen, derfor kaldet metode lokal indre klasse.
Bemærk, at indre klasse også har sin egen metodedefinition.

instantiere en metode lokal indre klasse
foregående kode erklærer en metode lokal indre klasse, men det skaber ikke noget objekt af indre klasse.
nu opstår spørgsmålet, hvordan man opretter et objekt af metode lokal indre klasse.
da en metode lokal indre klasse er defineret inde i en metode, er den kun synlig inde i denne metode, og dens objekt kan også kun oprettes inde i denne metode.
nedenfor kode skaber et objekt af metode lokal indre klasse og kalder sin metode.

// 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(); }}

når ovenstående kode udføres, følger output

metode lokal indre klassemetode kaldet

dette viser, at når ydre klassemetode kaldes, opretter den et objekt af indre klasse og kalder den indre klassemetode.

metode lokal indre klasse : punkter at huske
erklæring, der skaber et objekt af metode lokal indre klasse skal skrives uden for klassekroppen.
således skal linjen Inner innerObject = new Inner(); komme, når den lokale klasse slutter.

  1. en metode lokal indre klasse kan kun instantieres inden for den metode, hvor den erklæres.
    dette giver mening, da en metodeklasse kun er synlig inde i metoden, og dens objekt kan derfor kun oprettes inde i denne metode.
  2. en metode lokal indre klasse kan ikke få adgang til de lokale variabler af den metode, hvori den er erklæret.
    hvis det skal have adgang til dem, skal de markeres final.
    dette gælder før java 8.
  3. du kan ikke få adgang til en metode lokal variabel i en metode lokal indre klasse og derefter tildele den igen. Dette vil være en compiler fejl.
    dette gælder fra java 8, Da versioner før java 8 ikke engang giver dig adgang til en metode lokal variabel inde i den indre klasse.
  4. en metode lokal indre klasse kan få adgang til felterne og andre metoder i den klasse, som metoden indeholdende indre klasse tilhører.
  5. en metode lokal indre klasse kan få adgang til static felterne og andre staticmetoder for den klasse, som metoden, der indeholder indre klasse, kun tilhører, når den indeholdende metode er static.

3. Anonyme indre klasser
anonym betyder, hvis navn ikke er kendt. I forbindelse med java er en anonym klasse en, der ikke har noget navn.
udtrykket anonym klasse gælder kun for Indre klasser, da ydre klasser skal have et navn.
en anonym klasse er en indre klasse, fordi den altid vil blive defineret i en anden klasse.

typer af Anonym klasse i java
I faktisk er en anonym klasse en implementering af en allerede eksisterende klasse eller en grænseflade, der er skrevet et andet sted, men den defineres igen i en anden klasse efter behov.
dette lyder måske forvirrende, men de følgende eksempler vil tydeliggøre konceptet.

baseret på, om den anonyme klasse er en implementering af en klasse eller en grænseflade, kan den tilhøre følgende to kategorier

A. Underklasse af en klasse
lad os starte med et eksempel først

// 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"); } };}

i ovenstående eksempel er der en klasse med navnet hjemmeside som allerede er oprettet.
en anden klasse SearchEngine omdefinerer denne klasse, implementerer dens metode og tildeler den til en referencevariabel, der er af samme type som den faktiske klasse.
det er også muligt at kalde den nyligt implementerede metode ved hjælp af denne referencevariabel.

Husk, at den nyligt implementerede anonyme klasse er en underklasse af den faktiske klasse.
Det følger polymorfisme, og dets objekt kan overføres overalt, hvor formålet med Hjemmesideklassen forventes.
gå gennem nedenstående eksempel til illustration.

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); }}

i stedet for at foruddefinere implementeringen af hjemmeside klasse, kan det defineres, hvor det er nødvendigt, det vil sige, mens du kalder metoden.
således kan hovedmetoden ændres som

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"); } });}

ovenstående implementering er ikke tildelt nogen referencevariabel, den har intet navn og dermed navnet anonymt.

det er ikke nødvendigt, at begge klasser er i samme fil eller pakke. De kan placeres hvor som helst i forhold til hinanden.

B. Implementer af Interface
en anonym klasse kan også defineres som implementer af en grænseflade.
i dette tilfælde vil det definere implementeringen af metoder, der er erklæret i grænsefladen, og kan overføres hvor som helst genstanden for grænsefladen forventes.
se nedenstående eksempel for at gøre det klart.

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); }}

som før kan implementering af interface som anonym klasse oprettes, hvor det kræves som vist nedenfor.

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"); } });}
Bemærk brugen af new søgeord før interfacenavnet. Anonym klasse er det eneste sted, hvor det er muligt.

polymorfisme i Anonyme klasser
som tidligere nævnt følger anonyme klasser polymorfisme.
da de er underklasser, bør de følge polymorfisme. Dette afsnit beskriver hvordan.
overvej nedenstående klasse.

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(); }}

ovenstående kode definerer et klasse Metal med en enkelt metode.
denne klasse implementeres igen anonymt i en anden klasse MetalDriver, hvor der tilføjes en ny metode til dens definition, som ikke er til stede i den faktiske klasse.

nu når denne nye metode kaldes, klager kompilatoren med en fejl

metoden hasLustre() er udefineret for typen Metal.

dette skyldes, at Anonym klasse er en underklasse, mens referencen er af faktisk klasse(som er overordnet).
Compiler kunne ikke finde den nye metode i forældreklasse og markerer en fejl.

fejlen etablerer således to fakta:
(i) anonym klasse er en underklasse af den faktiske klasse, og
(ii) anonyme klassedefinitioner følger polymorfisme.

brug af Anonym klasse
Antag, at du skal kalde en metode, der tager et argument af en type, der er en grænseflade.
nu hører denne grænseflade til et eksternt bibliotek, og du har ikke en klasse, der implementerer denne grænseflade.
Hvordan vil du kalde denne metode. Hvis du passerer null, er der risiko for undtagelser fra køretid.
anonym klasse til undsætning.
nu Kan du oprette en anonym klasse, der implementerer denne grænseflade og videregive den over metoden, der giver implementering af dens metoder efter dine behov.
eksempel følger.

// 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(); }}

ovenstående kode har en grænseflade med en enkelt metode og en klasse, Hvis metode du skal ringe fra din kode.

metoden i denne klasse tager et argument af typen interface, men du har ikke en klasse, der implementerer denne grænseflade.
hvis du sender nulltil metodeargumentet, vil det straks kaste en java.lang.NullPointerException.
se på, hvordan du kan kalde denne metode ved hjælp af Anonym klasse.

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 } }); }}

Bemærk brugen af Anonym interface implementering til at kalde metoden.
dette er den største fordel ved anonyme klasser.
4. Statisk indlejret klasse
en statisk klasse, der er defineret i en anden klasse, er en statisk indlejret klasse. Det er defineret ligesom en normal klasse forud for statisk søgeord.
Husk, at der ikke er noget som statisk klasse, en statisk indlejret klasse er bare et statisk medlem af sin ydre klasse.
da det er et statisk medlem, gælder følgende for en statisk indlejret klasse.

  1. det kan tilgås af den ydre klasse direkte uden at have sin forekomst.
  2. det kan kun få adgang til statiske medlemmer af sin ydre klasse, men ikke dens instansvariabler eller metoder.

statisk indlejret klasseeksempel

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(); }}

som du kan se fra ovenstående eksempel, at for at få adgang til statisk indlejret klasse kræves der ikke en forekomst af ydre klasse, og den kan fås direkte adgang til den.
Bemærk, at objekt af statisk indlejret klasse ikke kan få adgang til ikke-statiske medlemmer af ydre klasse. I ovenstående eksempel kan indlejrede klasse instans ikke påberåbe outerMethod af ydre klasse.

lad os justere i

  1. når en klasse, der indeholder indre klasse, er kompileret, genereres der 2 klassefiler :
    en til ydre klasse og en til indre klasse.
    Eksempel, Ydre.klasse og ydre $ indre.klasse for ydre klasse ydre og indre klasse indre henholdsvis..
  2. klassefil af indre klasse kan ikke udføres direkte ved hjælp af java-kommando.
  3. en normal indre klasse kan ikke have static data medlemmer eller metoder.
  4. en indre klasse kan have en konstruktør.
  5. en metode lokal klasse kan kun instantieres inden for den metode, hvori den er defineret.
  6. en metode lokal klasse defineret i static metode kan kun få adgang til static medlemmer af den omsluttende klasse.
  7. en anonym klasse, der implementerer en grænseflade, kan kun implementere en grænseflade i modsætning til normale klasser, der kan implementere mange.
  8. en anonym klasse kan ikke udvide en klasse og implementere en grænseflade på samme tid, som normale klasser kan.
  9. anonyme klassedefinitioner slutter med }; (Bemærk semikolon).
  10. anonyme klasser, der er defineret som et argument, mens du kalder en metode, slutter med }); (Bemærk semikolon).
  11. du kan ikke kalde en metode på anonym Klasse reference, som ikke er til stede i faktiske klasse.
  12. en indre klasse forud for static er kendt som en indlejret klasse, ikke en indre klasse.

Leave a Reply