clase interioare în java

clasă interioară însemnând
după cum afirmă numele său, o clasă din interiorul unei alte clase se numește clasă interioară.
clasele interioare împărtășesc o relație specială cu clasa sa care conține, prin faptul că are acces la toți membrii clasei exterioare(chiar și la cei private).
acest lucru se datorează faptului că o clasă interioară este, de asemenea, un membru al clasei exterioare la fel ca alte domenii și metode.
deoarece o clasă interioară este o clasă din interiorul unei alte clase, ea poate fi denumită și o clasă imbricată.
tipuri de clase interioare
o clasă interioară poate fi de următoarele tipuri.

  1. clasă interioară normală sau regulată sau imbricată(denumită în mod normal doar clasă interioară)
  2. metodă clasă interioară locală.
  3. clasa interioară anonimă.
  4. clasa imbricată statică

1. Clasa interioară imbricată
această secțiune va săpa în toate detaliile unei clase interioare. Pentru simplitate, luați în considerare următoarele clase

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

aici exterior este clasa exterioară și interior este clasa interioară care este conținută în interior exterior.

crearea obiectului clasei interioare
o clasă interioară se află în interiorul unei alte clase. Clasa care conține se numește clasă exterioară. Astfel, o clasă interioară nu poate exista fără o clasă exterioară și același lucru se aplică obiectului său(sau instanței).
un obiect al clasei interioare nu poate exista fără un obiect al clasei exterioare.
aceasta înseamnă că pentru a crea o instanță a clasei interioare, trebuie să aveți o instanță a clasei exterioare.
astfel, obiectul clasei interioare poate fi creat prin metoda dată mai jos.

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

după cum reiese clar din exemplu, pentru a crea un obiect al clasei interioare, este necesar un obiect al clasei exterioare.
există, de asemenea, o metodă de mână scurtă pentru crearea obiectului de clasă interioară.

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

această metodă necesită, de asemenea, obiect de clasă exterioară.
doar Remember….An obiectul clasei interioare nu poate fi creat fără un obiect al conținutului său (sau al clasei exterioare).

crearea obiectului clasei interioare în clasa exterioară
exemplul anterior presupune că instanțiați clasa interioară de undeva din afara clasei exterioare.
dar, în majoritatea cazurilor, un obiect al clasei interioare este necesar doar în interiorul clasei exterioare, deoarece clasa exterioară folosește clasa interioară.
Deci, cum putem crea un obiect al clasei interioare din interiorul clasei exterioare?
luați în considerare clasa de probă modificată de mai jos.

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

observați linia Inner innerObject = new Inner();.
anterior s-a afirmat că un obiect de clasă interioară nu poate fi creat fără un obiect de clasă exterioară, dar fragmentul de cod de mai sus o face. Confuz !!!!
sintaxa de mai sus este validă deoarece este scrisă în interiorul unei metode de clasă exterioară.
când se execută acest cod, există deja o instanță de clasă exterioară prezentă, care execută metoda.

amintiți-vă întotdeauna, pentru a crea(sau accesa) un obiect al clasei interioare, ar trebui să existe o instanță a clasei exterioare.

pentru a rezuma,

  1. când un obiect al clasei interioare este creat din interiorul clasei exterioare, acesta poate fi creat direct ca Inner innerObject = new Inner();.
  2. când un obiect al clasei interioare este creat din afara clasei exterioare, trebuie să fie creat ca Inner innerObject = new Outer().new Inner();.

când sunt tipărite obiecte din clasa exterioară și interioară, urmează ieșirea generată:

instanță de clasă exterioară: instanță de clasă interioară exterioară@659e0bfd
: Outer$Inner@2a139a55

referențierea instanței de clasă exterioară, câmpuri și metode din clasa interioară
o clasă interioară este, de asemenea, un membru al clasei sale care conține ca și alte câmpuri și metode.
astfel, poate accesa alte câmpuri și metode ale clasei exterioare în același mod în care alte câmpuri și metode se accesează reciproc, direct.
acest lucru este valabil atunci când accesați câmpuri și metode de clasă exterioară din clasa interioară.

dar, atunci când se referă la instanța de clasă exterioară, există o diferență. Pentru a face referire la instanța curentă a unei clase, se utilizează cuvântul cheie this.
în cazul clasei interioare, utilizarea this clasa interioară interioară se referă la instanța actuală a clasei interioare și nu la clasa sa exterioară.
pentru referențierea instanței de clasă exterioară din clasa interioară, trebuie să adăugăm numele clasei la cuvântul cheie this.

astfel, pentru a face referire la instanța de clasă exterioară din clasa interioară, utilizați sintaxa Outer.this.
consultați exemplul de mai jos pentru înțelegere.

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

ieșire

câmp exterior: exterior
instanță interioară:
instanță exterioară:

2. Metodă clasă interioară locală
după cum sugerează și numele, o clasă definită în interiorul unei metode este o metodă clasă interioară locală.
da, este posibil.
puteți defini o clasă în interiorul unei metode așa cum se arată mai jos.

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

codul de mai sus are o clasă exterioară care conține o metodă.
această metodă definește o clasă care se află în interiorul corpului metodei, de aici numită metodă clasă interioară locală.
observați că clasa interioară are, de asemenea, propria definiție a metodei.

instanțierea unei metode clasa interioară locală
codul precedent declară o metodă clasa interioară locală, dar nu creează niciun obiect al clasei interioare.
acum se pune întrebarea, Cum de a crea un obiect de metodă clasa interioară locală.
deoarece o clasă interioară locală a metodei este definită în interiorul unei metode, ea este vizibilă numai în interiorul acelei metode și obiectul ei poate fi creat și numai în interiorul acelei metode.
codul de mai jos creează un obiect al metodei clasa interioară locală și numește metoda sa.

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

când codul de mai sus este executat, în urma este de ieșire

Metoda Metoda clasei interioare locale numit

acest lucru arată că, atunci când se numește metoda clasei exterioare, se creează un obiect de clasă interioară și solicită metoda clasei interioare.

metoda clasa interioară locală : puncte de reținut
declarație care creează un obiect al metodei clasa interioară locală ar trebui să fie scrisă în afara corpului clasei.
astfel, linia Inner innerObject = new Inner(); ar trebui să vină după terminarea clasei locale.

  1. o metodă clasa internă locală poate fi instanțiată numai în interiorul metodei în care este declarată.
    acest lucru are sens, deoarece o clasă de metodă este vizibilă numai în interiorul metodei, astfel obiectul său poate fi creat numai în interiorul acelei metode.
  2. o metodă clasa interioară locală nu poate accesa variabilele locale ale metodei în care este declarată.
    dacă trebuie să le acceseze, acestea trebuie marcate final.
    acest lucru se aplică înainte de java 8.
  3. nu puteți accesa o variabilă locală de metodă în interiorul unei clase interioare locale de metodă și apoi să o re-atribuiți. Aceasta va fi o eroare de compilator.
    acest lucru este aplicabil din java 8, deoarece versiunile anterioare java 8 nu vă vor permite nici măcar să accesați o metodă variabilă locală în interiorul clasei interioare.
  4. o metodă clasa interioară locală poate accesa câmpurile și alte metode ale clasei căreia îi aparține metoda care conține clasa interioară.
  5. o metodă clasa interioară locală poate accesa câmpurile static și alte metode staticale clasei căreia îi aparține metoda care conține clasa interioară numai atunci când metoda care conține este static.

3. Clase interioare anonime
anonim înseamnă al cărui nume nu este cunoscut. În contextul java, o clasă anonimă este una care nu are nume.
termenul clasă anonimă se aplică numai claselor interioare, deoarece clasele exterioare ar trebui să aibă un nume.
o clasă anonimă este o clasă interioară, deoarece va fi întotdeauna definită în interiorul unei alte clase.

tipuri de clase anonime în java
în realitate, o clasă anonimă este o implementare a unei clase deja existente sau a unei interfețe care este scrisă în altă parte, dar este definită din nou în interiorul unei alte clase, după cum este necesar.
acest lucru poate părea confuz, dar exemplele care urmează vor clarifica conceptul.

pe baza faptului că clasa anonimă este o implementare a unei clase sau a unei interfețe, aceasta poate aparține următoarelor două categorii

A. Subclasa unei clase
să începem cu un exemplu mai întâi

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

în exemplul de mai sus, există o clasă numită site web care este deja creată.
o altă clasă SearchEngine redefinește această clasă, implementează metoda sa și o atribuie unei variabile de referință care este de același tip cu clasa reală.
de asemenea, este posibil să apelați metoda nou implementată folosind această variabilă de referință.

amintiți-vă că clasa anonimă nou implementată este o sub-clasă a clasei reale.
urmează polimorfismul și obiectul său poate fi transmis oriunde se așteaptă obiectul clasei site-ului web.
parcurgeți exemplul de mai jos pentru ilustrare.

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

în loc de pre-definirea implementării clasei de site-uri web, aceasta poate fi definită acolo unde este necesar, adică în timp ce apelați metoda getWebsite.
astfel, metoda principală poate fi modificată ca

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

implementarea de mai sus nu este atribuită niciunei variabile de referință, nu are nume și, prin urmare, numele anonim.

nu este necesar ca ambele clase să fie în același fișier sau pachet. Ele pot fi localizate oriunde unul față de celălalt.

B. implementatorul interfeței
o clasă anonimă poate fi, de asemenea, definită ca implementatorul unei interfețe.
în acest caz, va defini implementarea metodelor declarate în interfață și poate fi transmisă oriunde se așteaptă obiectul interfeței.
consultați exemplul de mai jos pentru a clarifica.

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

ca și înainte, implementarea interfeței ca clasă anonimă poate fi creată acolo unde este necesar, așa cum se arată mai jos.

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"); } });}
observați utilizarea new cuvânt cheie înainte de numele interfeței. Clasa anonimă este singurul loc unde este posibil.

polimorfismul în clasele anonime
după cum sa menționat mai devreme, clasele anonime urmează polimorfismul.
deoarece sunt subclase, ar trebui să urmeze polimorfismul. Această secțiune va detalia cum.
luați în considerare clasa de mai jos.

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

codul de mai sus definește o clasă de Metal cu o singură metodă.
această clasă este implementată din nou anonim într-o altă clasă MetalDriver unde se adaugă o nouă metodă la definiția sa care nu este prezentă în clasa reală.

acum, când se numește această nouă metodă, compilatorul se plânge cu o eroare

metoda hasLustre() este nedefinită pentru tipul Metal.

acest lucru se datorează faptului că clasa anonimă este o subclasă în timp ce referința este de clasă reală(care este părintele).
compilatorul nu a putut găsi noua metodă în clasa părinte și semnalează o eroare.

astfel, eroarea stabilește două fapte:
(i) Clasa anonimă este o sub-clasă a clasei reale și
(ii) definițiile clasei anonime urmează polimorfismul.

utilizarea clasei anonime
să presupunem că trebuie să apelați o metodă care ia un argument de un tip care este o interfață.
acum, această interfață aparține unei biblioteci externe și nu aveți o clasă care implementează această interfață.
cum veți numi această metodă. Dacă treceți null, atunci există riscul de excepții în timpul rulării.
clasa anonimă pentru salvare.
acum Puteți crea o clasă anonim care pune în aplicare această interfață și trece-l peste metoda furnizarea de punere în aplicare a metodelor sale ca pe nevoile dumneavoastra.
urmează exemplul.

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

codul de mai sus are o interfață cu o singură metodă și o clasă A cărei metodă trebuie să apelați din codul dvs.

metoda acestei clase ia un argument de interfață de tip, dar nu aveți o clasă care implementează această interfață.
dacă treceți nullla argumentul metodei, acesta va arunca imediat un java.lang.NullPointerException.
aruncați o privire la modul în care puteți apela această metodă folosind clasa anonimă.

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

observați utilizarea implementării interfeței anonime pentru a apela metoda.
acesta este cel mai mare beneficiu al claselor anonime.
4. Clasa statică imbricată
o clasă statică care este definită în interiorul unei alte clase este o clasă statică imbricată. Este definit la fel ca o clasă normală precedată de cuvinte cheie statice.
amintiți-vă că nu există nimic ca clasă statică, o clasă imbricată statică este doar un membru static al clasei sale exterioare.
deoarece este un membru static, următoarele se aplică unei clase imbricate statice.

  1. poate fi accesat direct de clasa exterioară fără a avea instanța sa.
  2. poate accesa doar membrii statici ai clasei sale exterioare, dar nu variabilele sau metodele sale de instanță.

exemplu de clasă imbricată statică

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

după cum puteți vedea din exemplul de mai sus, că pentru a accesa clasa imbricată statică, nu este necesară o instanță a clasei exterioare și poate fi accesată direct.
rețineți că obiectul clasei imbricate statice nu poate accesa membrii non-statici ai clasei exterioare. În exemplul de mai sus, instanța de clasă imbricată nu poate invoca outerMethod din clasa exterioară.

să tweak în

  1. atunci când o clasă care conține clasa interior este compilat, apoi 2 fișiere de clasă sunt generate :
    unul pentru clasa exterior și unul pentru clasa interior.
    Exemplu, Exterior.clasa și exterior$interior.clasa pentru clasa exterioară exterior și interior clasa interior respectiv..
  2. fișier clasă de clasă interioară nu poate fi executat direct folosind comanda java.
  3. o clasă interioară normală nu poate avea static membri sau metode de date.
  4. o clasă interioară poate avea un constructor.
  5. o clasă locală de metodă poate fi instanțiată numai în interiorul metodei în care este definită.
  6. o clasă locală de metodă definită în metoda static poate accesa numai static membrii clasei de închidere.
  7. o clasă anonimă care implementează o interfață, poate implementa o singură interfață, spre deosebire de clasele normale care pot implementa multe.
  8. o clasă anonimă nu poate extinde o clasă și implementa o interfață în același timp pe care clasele normale o pot.
  9. definițiile claselor anonime se termină cu }; (observați punctul cu două puncte).
  10. clase anonime care sunt definite ca un argument în timp ce apelarea unei metode se termină cu }); (observați semi-colon).
  11. nu puteți apela o metodă pe referință de clasă anonimă care nu este prezentă în clasa reală.
  12. o clasă interioară precedată de static este cunoscută ca o clasă imbricată, nu o clasă interioară.

Leave a Reply