Innere Klassen sind nicht ganz leicht zu verstehen, aber um es schlicht zu sagen: Sie sind einfach eine Klasse, die eine andere Klasse enthält.

So wie ein Mensch aus Körperstrukturen wie Gehirn, Gliedmaßen und Organen besteht, entspricht eine innere Klasse einem dieser Organe, beispielsweise dem Herzen: Auch sie hat ihre eigenen Eigenschaften und Verhaltensweisen (Blut, Schlagen).

Offensichtlich kann ein Herz nicht allein durch Eigenschaften oder Methoden dargestellt werden; es benötigt eine Klasse.

Und das Herz befindet sich im menschlichen Körper, so wie eine innere Klasse sich innerhalb ihrer äußeren Klasse befindet.

Beispiel 1: Grundstruktur einer inneren Klasse

//外部类
class Out {
    private int age = 12;
     
    //内部类
    class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
        //或者采用下种方式访问
        /*
        Out out = new Out();
        Out.In in = out.new In();
        in.print();
        */
    }
}

Ausgabe: 12

Aus dem obigen Beispiel ist leicht zu erkennen, dass innere Klassen tatsächlich die gute Codestruktur ernsthaft beschädigen, aber warum verwendet man trotzdem innere Klassen?

Weil eine innere Klasse die Membervariablen der äußeren Klasse (einschließlich privater) frei verwenden kann, ohne ein Objekt der äußeren Klasse zu erzeugen; das ist auch der einzige Vorteil innerer Klassen.

So wie das Herz direkt auf das Blut des Körpers zugreifen kann, anstatt dass ein Arzt Blut abnimmt.

Nach der Kompilierung des Programms werden zwei .class-Dateien erzeugt, nämlich Out.class und Out$In.class.

Hier steht $ für den Punkt in Out.In im obigen Programm.

Out.In in = new Out().new In()Damit kann ein Objekt der inneren Klasse erzeugt werden. Bei diesem Ansatz sind zwei kleine Punkte zu beachten:

  • 1. Das Out am Anfang wird verwendet, um anzugeben, zu welcher äußeren Klasse das zu erzeugende Objekt der inneren Klasse gehört.
  • 2. Zuerst müssen Sie ein Objekt der äußeren Klasse haben, bevor Sie ein Objekt der inneren Klasse erzeugen können, denn der Zweck der inneren Klasse besteht darin, auf die Mitgliedsvariablen der äußeren Klasse zuzugreifen.
class Out {
    private int age = 12;
     
    class In {
        private int age = 13;
        public void print() {
            int age = 14;
            System.out.println("局部变量:" + age);
            System.out.println("内部类变量:" + this.age);
            System.out.println("外部类变量:" + Out.this.age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out().new In();
        in.print();
    }
}

Ausgabe:

局部变量:14
内部类变量:13
外部类变量:12

Aus Beispiel 1 ist ersichtlich, dass die innere Klasse, wenn es keine gleichnamigen Mitgliedsvariablen oder lokalen Variablen gibt, direkt auf die Mitgliedsvariablen der äußeren Klasse zugreift, ohneOut.this.propertyName angeben zu müssen。

Andernfalls überschreiben lokale Variablen in der inneren Klasse die Mitgliedsvariablen der äußeren Klasse.

Um auf die eigenen Mitgliedsvariablen der inneren Klasse zuzugreifen, können Siethis.propertyNameverwenden, und um auf die Mitgliedsvariablen der äußeren Klasse zuzugreifen, müssen SieOut.this.propertyName verwenden。

Beispiel 3: Statische innere Klasse

class Out {
    private static int age = 12;
     
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}

Ausgabe: 12

Man kann sehen, dass die innere Klasse, wenn Sie sie mit static statisch machen, nur auf die statischen Mitgliedsvariablen der äußeren Klasse zugreifen kann, was eine Einschränkung ist.

Zweitens kann, da die innere Klasse statisch gemacht wurde, Out.In als Ganzes behandelt werden, und Sie können direkt ein Objekt der inneren Klasse mit new erzeugen (wobei über den Klassennamen auf statische Elemente zugegriffen wird; es spielt keine Rolle, ob ein Objekt der äußeren Klasse erzeugt wird).

Beispiel 4: Private innere Klasse/h3>
class Out {
    private int age = 12;
     
    private class In {
        public void print() {
            System.out.println(age);
        }
    }
    public void outPrint() {
        new In().print();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        //此方法无效
        /*
        Out.In in = new Out().new In();
        in.print();
        */
        Out out = new Out();
        out.outPrint();
    }
}

Ausgabe: 12

Wenn eine innere Klasse nur durch Methoden in der äußeren Klasse bearbeitet werden soll, dann kannst du die innere Klasse als private deklarieren.

Im obigen Code müssen wir ein Objekt der Klasse In innerhalb der Klasse Out erstellen, um damit zu arbeiten, und wir können nicht mehrOut.In in = new Out().new In()verwenden, um ein Objekt der inneren Klasse zu erstellen.

Mit anderen Worten: Zu diesem Zeitpunkt kann die innere Klasse nur von der äußeren Klasse kontrolliert werden.

Genauso wie mein Herz nur von meinem Körper kontrolliert werden kann; andere Menschen können nicht direkt darauf zugreifen.

Beispiel 5: Methodenlokale innere Klasse

class Out {
    private int age = 12;
 
    public void Print(final int x) {
        class In {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }
        new In().inPrint();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out out = new Out();
        out.Print(3);
    }
}

Ausgabe:

3
12

Im obigen Code haben wir die innere Klasse in eine Methode der äußeren Klasse verschoben und dann innerhalb der Methode der äußeren Klasse ein Objekt der inneren Klasse erstellt, um die Methode der inneren Klasse aufzurufen.

Wenn wir an diesem Punkt Parameter in die Methode der äußeren Klasse übergeben müssen, dann müssen die Methodenparameter der äußeren Klasse mit final definiert werden.

Was final betrifft, hat es hier keine besondere Bedeutung; es ist nur Formsache.