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

Zusammenfassung der Verwendung von Java-Internklassen

1.什么是内部类?63;

定义在类内部的类,称之为内部类

 public class Out{
   class In{ //此时In就是内部类
   } 
}

2.为什么要使用内部类?63;

1)增强封装,把内部类隐藏在外部类中,不允许其他类来访问内部类

2)内部类能提高代码的可读性和可维护性

3.内部类的分类

对于内部类的分类,可以对比于成员变量的分类。

我们可以根据不同的修饰符或者定义的不同位置把成员变量,可以细分为:类成员变量,实例成员变量,局部变量。

内部类看做是外部类的一个成员,那么内部类可以使用public/缺省/protected/private修饰。还可以是static修饰。

同理,内部类也根据使用不同的修饰符或者定义的不同位置,将其分成4类:

1)实例内部类:内部类没有使用static修饰

2)静态内部类:内部类使用static修饰

3)局部内部类:在方法中定义的内部类

4)匿名内部类:只能使用一次,属于内部类的一种特殊情况

3.1实例内部类:

1)定义:实例内部类,即没有使用static修饰的内部类。这说明,实例内部类属于外部类的对象,不属于外部类本身(类比字段)。

2)创建实例内部类

//Äußere Klasse
class Outter {
 // Instanzinterne Klasse: Ohne static zu dekoriert
 class Inner {
 }
}
public class InnerDemo1 {
 public static void main(String[] args) {
 // 创建实例内部类,没有使用static修饰,属于外部类的对象,因此,创建实例内部类前,必须存在外部类对象
 Outter out = new Outter();
 // 通过外部类对象创建内部类对象
 Outter.Inner in = out.new Inner();
 }
}

3) Merkmale:

a.由创建实例内部类的过程可知,当存在内部类对象时,一定存在外部类对象。

b.实例内部类的实例自动持有外部类的实例的引用,实例内部类可以无条件访问外部类的所有字段和方法

注意:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象

c.外部类中不能直接访问内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问

//Äußere Klasse
class Outter {
 private String name = "out";
 private Integer age = 17;
 // Instanzinterne Klasse: Ohne static zu dekoriert
 class Inner {
 private Integer age = 18; // Verdeckungseffekt, verdeckt das age der äußeren Klasse
 Inner() {
  // Merkmale:1. Die Instanzinterne Klasse kann direkt auf die Mitglieder der äußeren Klasse zugreifen
  // 2. Es tritt ein Verdeckungseffekt auf, wenn eine Instanzinterne Klasse und die äußere Klasse Felder oder Methoden mit demselben Namen haben
  System.out.println(name + this.age);// Ausgabe out18
  // Wenn zu diesem Zeitpunkt auf das age der äußeren Klasse zugegriffen werden muss, ist die Syntax: äußere Klasse.this.age
  System.out.println(Outter.this.age);// Ausgabe17
 }
 }
}

Zusammenfassung: Einfach gesagt, schaut man auf den Gültigkeitsbereich der Variablen, der Gültigkeitsbereich der Mitglieder der äußeren Klasse ist die gesamte äußere Klasse, und die interne Klasse ist innerhalb der äußeren Klasse (kann als Feld der äußeren Klasse betrachtet werden), daher kann die interne Klasse auf die äußere Klasse zugreifen. Wenn die äußere Klasse auf die Mitglieder der internen Klasse zugreifen möchte, kann dies so verstanden werden: Die Mitglieder der internen Klasse gehören zur internen Klasse und sind innerhalb der internen Klasse gültig. Wenn die interne Klasse nicht existiert, existieren auch die Mitgliedsvariablen nicht, daher kann die äußere Klasse die Mitglieder der internen Klasse nicht direkt zugreifen und muss zunächst ein Objekt der Mitgliedsklasse erstellen, um über den Zeiger auf dieses Objekt auf die Mitgliedsvariablen zuzugreifen.

3.2Statische interne Klasse

1) Definition: Innere Klassen, die mit static dekoriert sind. Daher gehört diese innere Klasse zur äußeren Klasse selbst und nicht zu einem Objekt der äußeren Klasse

2) Erstellen der statischen internen Klasse

//Äußere Klasse
class Outter {
 // Statische interne Klasse: Verwendet static dekoriert
 static class Inner {
 }
}
public class InnerDemo2 {
 public static void main(String[] args) {
 // Da die statische interne Klasse zur äußeren Klasse selbst gehört, kann auf diese direkt über den Klassennamen der äußeren Klasse zugegriffen werden (Vergleich mit Feldern)
 Outter.Inner in = new Outter.Inner();
 }
}

3) Merkmale:

a. Bei der Erstellung eines Instanzes der internen Klasse muss keine Instanz der äußeren Klasse erstellt werden.

b. Die statische interne Klasse kann direkt auf die statischen Mitglieder der äußeren Klasse zugreifen, wenn auf die Instanzmitglieder der äußeren Klasse zugegriffen werden muss, muss über die Instanz der äußeren Klasse zugegriffen werden.

Einfach gesagt: Statische Mitglieder gehören zur Klasse, nicht statische Mitglieder gehören zum Objekt. Wenn man auf die Instanzmitglieder der äußeren Klasse (nicht statische Mitglieder) zugreifen möchte, muss natürlich zunächst ein Objekt der äußeren Klasse existieren. Da die Erstellung der statischen internen Klasse jedoch ohne Objekt der äußeren Klasse erfolgt, muss auf die Instanzmitglieder der äußeren Klasse zugegriffen werden, indem über die Instanz der äußeren Klasse zugegriffen wird.

c. In der statischen internen Klasse können statische und Instanzmitglieder definiert werden.

d. Der Testklasse kann auf die statischen Mitglieder der statischen internen Klasse über den vollständigen Klassennamen direkt zugreifen.

//Äußere Klasse
class Outter {
 static String name = "outter";
 public Integer age = 17;
 // Statische interne Klasse: Verwendet static dekoriert
 static class Inner {
 Inner() {
  // Static interne Klassen können direkt auf die statischen Mitglieder der äußeren Klasse zugreifen
  System.out.println(name);// Ausgabe outter
  // Um auf Instanzmember der äußeren Klasse zuzugreifen, muss über eine Instanz der äußeren Klasse zugegriffen werden.
  System.out.println(new Outter().age);// Ausgabe 17
 }
 }
}

3.3lokale innere Klasse (fast nie verwendet)

1): Definition: Eine innere Klasse, die in einer Methode definiert ist, hat einen Sichtbereich, der der aktuellen Methode entspricht und derselben Stufe wie lokale Variablen ist, daher können lokale innere Klassen nur in Methoden verwendet werden.

Beachten Sie, dass lokale innere Klassen und lokale Variablen innerhalb einer Methode ebenfalls keine Modifikatoren wie public, protected, private und static haben dürfen.

public class InnerDemo3 {
 public static void main(String[] args) {
 // lokale innere Klasse
 class Inner {
 }
 }
}

2) Merkmale:

a. Lokale innere Klassen und Instanzinnere Klassen können keine statischen Member enthalten. (Lokale innere Klassen gehören zu Methoden, während statische Member zu Klassen gehören)

b. Lokale innere Klassen und Instanzinnere Klassen können alle Member der äußeren Klasse zugreifen.

c. Lokale innere Klassen müssen lokale Variablen mit final modifizieren, in Java8ist automatisch implizit final (Syntaxsüße) hinzugefügt.

Ursache: Nachdem ein Methodenaufruf abgeschlossen ist und der aktuelle Stacktrace zerstört wurde, werden der Speicherplatz für lokale Variablen innerhalb der Methode vollständig zerstört. Es kann jedoch der Fall auftreten, dass ein Objekt der inneren Klasse noch im Heap-Speicher vorhanden ist, bis es nicht mehr referenziert wird. In diesem Fall könnte eine Situation auftreten: Die innere Klasse versucht, auf eine nicht existierende lokale Variable zuzugreifen. Um dieses Problem zu vermeiden, verwenden wir den Modifikator final für lokale Variablen, um sie zu Konstanten zu machen, die im Speicherbereich verbleiben, selbst wenn die Methode zerstört wird, bleibt die lokale Variable im Speicher, und das Objekt kann weiterhin darauf zugreifen.

public class InnerDemo3 {
 public static void main(String[] args) {
 int age = 17;
 final int num = 15;
 // lokale innere Klasse
 class Inner {
  public void test() {
  // Fehler: Cannot refer to a non-final Variable age inside an inner class defined in a different method
  System.out.println(age);
  System.out.println(num);// Richtig
  }
 }
 }
}

3.4Anonyme innere Klasse (am häufigsten verwendet)

1): Definition: Eine anonyme innere Klasse ist eine lokale innere Klasse ohne Namen und ist geeignet für Klassen, die nur einmal verwendet werden.

2) Anlegen einer anonymen inneren Klasse:

Eine anonyme innere Klasse hat selbst keinen Konstruktor, aber ruft den Konstruktor der Oberklasse auf. Im Allgemeinen wird eine anonyme innere Klasse verwendet, um andere Klassen zu vererben oder Interfaces zu implementieren, erfordert jedoch keine zusätzlichen Methoden, sondern nur die Implementierung oder Überschreibung der vererbten Methoden.

Hinweis: Eine anonyme innere Klasse muss eine Oberklasse oder ein Interface implementieren, aber kann höchstens eine Oberklasse oder ein Interface implementieren.

//Definieren Sie ein Interface
interface Person {
 public void eat();
}
public class AnonymousDemo {
 public static void main(String[] args) {
 // Verwenden Sie anonyme Innere Klassen
 Person p = new Person() {
  public void eat() {
  System.out.println("eat something");
  }
 };
 p.eat();
 }
}

4.Zusammenfassung

5.Interviewfragen

public class Outer {
 public void someOuterMethod() {
 // Line 3
 }
 public class Inner {
 }
 public static void main(String[] argv) {
 Outer o = new Outer();
 // Line 8
 }
}
/*
 * Which instantiates an instance of Inner&63;
A. new Inner(); // At line 3
B. new Inner(); // At line 8
C. new o.Inner(); // At line 8
D. new Outer.Inner(); // At line 8
 */

Antwort A.new Inner(); ist äquivalent zu this.new Inner(); Es existiert bereits ein Objekt der Klasse Outer.

line 8 Die korrekte Schreibweise wäre: o.new Inner();

Das ist der gesamte Inhalt dieses Artikels. Ich hoffe, dieser Artikel kann Ihnen bei Ihrem Lernen oder Ihrer Arbeit helfen und ich hoffe auch, dass Sie die Anstrengungen des呐喊教程 unterstützen!

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt keine rechtlichen Verantwortlichkeiten. Wenn Sie urheberrechtswidrige Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3Bitte ersetzen Sie bei einer Beschwerde das # durch @ und senden Sie eine E-Mail mit relevanten Beweisen. Sobald überprüft, wird die fragliche urheberrechtswidrige Inhalte sofort gelöscht.

Gefällt Ihnen auch