English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

java内部类使用总结

1. Cos'è una classe interna?

Le classi definite all'interno di una classe sono chiamate classi interne

 public class Out{
   class In{ // In questo momento In è una classe interna
   } 
}

2. Perché utilizzare le classi interne?

1) Migliorare l'encapsulation, nascondere le classi interne nella classe esterna, non permettere ad altre classi di accedere alle classi interne

2) Le classi interne possono migliorare la leggibilità e la manutenibilità del codice

3. Classificazione delle classi interne

La classificazione delle classi interne può essere paragonata alla classificazione delle variabili di membro.

Possiamo dividere le variabili membro in base a diversi modificatori o posizioni di definizione: variabili membro della classe, variabili membro dell'istanza, variabili locali.

Le classi interne possono essere considerate come un membro della classe esterna, quindi le classi interne possono utilizzare public/defitto/protected/private e possono essere statiche.

Analogamente, le classi interne sono divise in 4 tipi in base all'uso di diversi modificatori o alla definizione in diverse posizioni:

1) Classe interna dell'istanza: la classe interna non utilizza static

2) Classe interna statica: la classe interna utilizza static

3) Classe interna locale: definita all'interno di un metodo

4) Classe interna anonima: può essere utilizzata una volta sola, è una speciale situazione della classe interna

3.1 Classe interna dell'istanza:

1) Definizione: classe interna dell'istanza, ossia la classe interna non utilizza static. Questo significa che la classe interna dell'istanza appartiene all'oggetto della classe esterna, non alla classe esterna stessa (analogo al campo).

2) Creazione della classe interna dell'istanza

// Classe esterna
class Outter {
 // Classe interna: non utilizza static
 class Inner {
 }
}
public class InnerDemo1 {
 public static void main(String[] args) {
 // Creazione della classe interna dell'istanza, non utilizza static, appartiene all'oggetto della classe esterna, quindi, prima di creare la classe interna dell'istanza, deve esistere un oggetto della classe esterna
 Outter out = new Outter();
 // Creazione dell'oggetto della classe interna tramite l'oggetto della classe esterna
 Outter.Inner in = out.new Inner();
 }
}

3) Caratteristiche:

a. Dalla procedura di creazione della classe interna, quando esiste un oggetto della classe interna, esiste necessariamente un oggetto della classe esterna.

b. L'istanza della classe interna mantiene automaticamente il riferimento all'istanza della classe esterna, la classe interna può accedere senza condizioni a tutti i campi e i metodi della classe esterna

Attenzione: quando la classe interna ha variabili o metodi con lo stesso nome della classe esterna, si verifica l'oscuramento

c. La classe esterna non può accedere direttamente ai membri della classe interna, è necessario creare un oggetto della classe interna del membro e accedervi tramite il riferimento a questo oggetto

// Classe esterna
class Outter {
 private String name = "out";
 private Integer age = 17;
 // Classe interna: non utilizza static
 class Inner {
 private Integer age = 18; // Fenomeno di oscuramento, oscura l'age della classe esterna
 Inner() {
  // Caratteristiche: 1. La classe interna può accedere direttamente ai membri della classe esterna
  // 2. Quando la classe interna e la classe esterna hanno campi o metodi con lo stesso nome, si verifica l'oscuramento
  System.out.println(name + this.age);// Stampa out18
  // Se necessario utilizzare l'age dell'esterno della classe, sintassi: esterna_classe.this.age
  System.out.println(Outter.this.age);// Stampa 17
 }
 }
}

Conclusione: In sintesi, è necessario guardare l'ambito delle variabili, l'ambito dei membri della classe esterna è l'intera classe esterna, mentre la classe interna è all'interno della classe esterna (può essere considerata un campo della classe esterna), la classe interna può naturalmente accedere alla classe esterna. Perché la classe esterna debba accedere ai membri della classe interna, può essere compreso così: i membri della classe interna appartengono alla classe interna, sono validi all'interno della classe interna. Se la classe interna non esiste, i variabili dei membri non esisteranno. Pertanto, la classe esterna non può accedere direttamente ai membri della classe interna, è necessario creare un oggetto della classe interna membro, quindi accedere ai membri tramite il riferimento dell'oggetto.

3.2 Classe interna statica

1) Definizione: La classe interna definita utilizzando static. Pertanto, la classe interna appartiene alla classe esterna stessa, non all'oggetto della classe esterna

2) Creazione della classe interna statica

// Classe esterna
class Outter {
 // Classe interna statica: utilizzata con static
 static class Inner {
 }
}
public class InnerDemo2 {
 public static void main(String[] args) {
 // Poiché la classe interna statica appartiene alla classe esterna stessa, può essere acceduta direttamente tramite il nome della classe esterna (simile a un campo)
 Outter.Inner in = new Outter.Inner();
 }
}

3) Caratteristiche:

a. Non è necessario creare un'istanza della classe esterna per creare un'istanza della classe interna.

b. La classe interna statica può accedere direttamente ai membri statici della classe esterna, se si desidera accedere ai membri dell'istanza della classe esterna, è necessario accedervi tramite l'istanza della classe esterna.

Semplice comprensione: i membri statici appartengono alla classe, i membri non statici appartengono all'oggetto. Se si desidera accedere ai membri dell'istanza della classe esterna (membri non statici), naturalmente, è necessario memorizzare l'oggetto della classe esterna. Poiché la creazione della classe interna statica non richiede un'istanza della classe esterna, se si desidera accedere ai membri dell'istanza della classe esterna, è necessario accedervi tramite l'istanza della classe esterna.

c. È possibile definire membri statici e membri di istanza nella classe interna statica.

d. Il test class può accedere direttamente ai membri statici della classe interna completa del nome della classe.

// Classe esterna
class Outter {
 static String name = "outter";
 public Integer age = 17;
 // Classe interna statica: utilizzata con static
 static class Inner {
 Inner() {
  // La classe interna statica può accedere direttamente ai membri statici della classe esterna
  System.out.println(name); // Output outter
  // Per accedere ai membri dell'istanza della classe esterna, è necessario accedervi tramite l'istanza della classe esterna.
  System.out.println(new Outter().age); // Output 17
 }
 }
}

3.3 Classe interna locale (quasi mai utilizzata)

1) Definizione: La classe interna definita all'interno di un metodo, la cui visibilità è il livello del metodo corrente e lo stesso livello dei variabili locali, quindi la classe interna locale può essere utilizzata solo all'interno del metodo.

Attenzione, le classi interne locali e le variabili locali all'interno del metodo non possono avere i modificatori public, protected, private e static.

public class InnerDemo3 {
 public static void main(String[] args) {
 // classe interna locale
 class Inner {
 }
 }
}

2) Caratteristiche:

a. Le classi interne locali e le classi interne di istanza non possono contenere membri statici. (Le classi interne locali appartengono al metodo, mentre i membri statici appartengono alla classe)

b. Le classi interne locali e le classi interne di istanza possono accedere a tutti i membri della classe esterna.

c. Le variabili locali accedute dalla classe interna locale devono essere modificate con final, in Java 8 viene aggiunto automaticamente in modo implicito (sugar sintattico).

Motivo: dopo che il metodo è stato chiamato e eseguito, lo stack frame del metodo viene distrutto, lo spazio dei variabili locali all'interno del metodo viene distrutto completamente. Ma l'oggetto della classe interna potrebbe ancora essere nella memoria heap, e verrà distrutto solo quando non c'è più alcun riferimento. In questo caso, si verifica una situazione in cui la classe interna deve accedere a una variabile locale inesistente. Per evitare questo problema, utilizziamo il modificatore final per le variabili locali, trasformandole in costanti che rimangono nel spazio di memoria, anche dopo la distruzione del metodo, la variabile locale rimane nella memoria, l'oggetto può continuare a essere mantenuto.

public class InnerDemo3 {
 public static void main(String[] args) {
 int età = 17;
 final int num = 15;
 // classe interna locale
 class Inner {
  public void test() {
  // Errore: Cannot refer to a non-final variable età inside an inner class defined in a different method
  System.out.println(età);
  System.out.println(num); // corretto
  }
 }
 }
}

3.4 Classi interne anonime (più frequentemente utilizzate)

1) Definizione: una classe interna anonima è una classe interna locale senza nome, adatta per classi che vengono utilizzate una sola volta.

2) Creare una classe interna anonima:

Le classi interne anonime non hanno un costruttore, ma chiamano il costruttore della classe superiore. Di solito, le classi interne anonime vengono utilizzate per ereditare da altre classi o implementare interfacce, non è necessario aggiungere metodi aggiuntivi, ma solo per implementare o sovrascrivere i metodi.

Attenzione: le classi interne anonime devono ereditare da una classe superiore o implementare un'interfaccia, ma non possono ereditare più di una classe superiore o implementare più di un'interfaccia.

// definire un'interfaccia
interface Person {
 public void eat();
}
public class AnonymousDemo {
 public static void main(String[] args) {
 // Utilizzo di classe interna anonima
 Person p = new Person() {
  public void eat() {
  System.out.println("eat something");
  }
 };
 p.eat();
 }
}

4. Sommario

5. Domande di intervista

public class Outer {
 public void someOuterMethod() {
 // Linea 3
 }
 public class Inner {
 }
 public static void main(String[] argv) {
 Outer o = new Outer();
 // Linea 8
 }
}
/*
 * Quale istanzia un'istanza di Inner?
A. new Inner(); // Alla riga 3
B. new Inner(); // Alla riga 8
C. new o.Inner(); // Alla riga 8
D. new Outer.Inner(); // Alla riga 8
 */

Risposta A.new Inner(); è equivalente a this.new Inner(); esiste già un oggetto della classe Outer.

line 8 Scrittura corretta, dovrebbe essere: o.new Inner();

Questo è tutto il contenuto dell'articolo, spero che il contenuto di questo articolo possa essere di aiuto alla tua apprendimento o lavoro, e spero di ricevere più supporto per il tutorial di grida!

Dichiarazione: il contenuto di questo articolo è stato preso da Internet, il copyright spetta agli autori originali, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non possiede il diritto di proprietà, non è stato elaborato manualmente e non assume alcuna responsabilità legale pertinente. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una email a: notice#oldtoolbag.com (al momento dell'invio dell'email, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.