wake-up-neo.net

Warum wird der Konstruktor der Superklasse aufgerufen, wenn das Objekt der Unterklasse deklariert wird? (Java)

Betrachten Sie diesen Code:

class Test {
    Test() {
        System.out.println("In constructor of Superclass");
    }

    int adds(int n1, int n2) {
        return(n1+n2);
    }

    void print(int sum) {
        System.out.println("the sums are " + sum);
    }
}


class Test1 extends Test {
    Test1(int n1, int n2) {
        System.out.println("In constructor of Subclass");
        int sum = this.adds(n1,n2);
        this.print(sum);
    }

    public static void main(String[] args) {
        Test1 a=new Test1(13,12);
        Test c=new Test1(15,14);
    }
}

Wenn wir einen Konstruktor in der Superklasse haben, wird dieser von jedem Objekt aufgerufen, das wir für die untergeordnete Klasse erstellen (z. B. Objekt a für Klasse Test1-Aufrufe Test1(int n1, int n2) und auch dessen übergeordnetes Test()). 

Warum passiert das?

Die Ausgabe dieses Programms ist:

Im Konstruktor von Superklasse

Im Konstruktor der Unterklasse

die summe beträgt 25

Im Konstruktor von Superklasse

Im Konstruktor der Unterklasse

die summen sind 29

32
aman_novice

Dadurch wird sichergestellt, dass beim Aufruf eines Konstruktors alle Felder seiner übergeordneten Klasse initialisiert werden können.

siehe 3.4.4 in hier

35
Ashkan Aryan

Ja. Eine Superklasse muss erstellt werden, bevor auch eine abgeleitete Klasse erstellt werden kann. Andernfalls werden einige Felder, die in der abgeleiteten Klasse verfügbar sein sollten, möglicherweise nicht initialisiert.

Eine kleine Anmerkung: Wenn Sie den Superklassenkonstruktor explizit aufrufen und ihm einige Parameter übergeben müssen:

baseClassConstructor(){
    super(someParams);
}

dann muss der Superkonstruktor der erste Methodenaufruf im abgeleiteten Konstruktor sein. Zum Beispiel wird dies nicht kompiliert:

baseClassConstructor(){
     foo(); 
     super(someParams); // compilation error
}
18
Heisenbug

super () wird in jedem Klassenkonstruktor automatisch vom Compiler hinzugefügt.

Wie wir gut wissen, wird der Standardkonstruktor automatisch vom Compiler bereitgestellt, fügt aber auch super () für die erste Anweisung hinzu. compiler liefert super () als erste Anweisung des Konstruktors.

 enter image description here

8
Jaimin Patel

Java-Klassen werden in der folgenden Reihenfolge instanziiert:

(zur Klassenlastzeit) 0. Initialisierer für statische Member und statische Initialisierungsblöcke in der Reihenfolge der Erklärung.

(bei jedem neuen Objekt) 

  1. erstellen Sie lokale Variablen für Konstruktorargumente
  2. wenn der Konstruktor mit dem Aufruf eines anderen Konstruktors für die Klasse _ beginnt, bewerten Sie die Argumente und kehren Sie zum vorherigen Schritt zurück. Alle Schritte Sind für diesen Konstruktor abgeschlossen, einschließlich der weiteren Rekursion von Konstruktoraufrufen, bevor Sie fortfahren.
  3. wenn die übergeordnete Klasse nicht durch die obigen Elemente erstellt wurde, erstellen Sie die die übergeordnete Klasse (mithilfe des Konstruktors no-arg, falls nicht angegeben). Gehen Sie wie in # 2 alle diese Schritte für die Oberklasse durch, einschließlich der Erstellung der Oberklasse " IT", bevor Sie fortfahren.
  4. initialisierer für Instanzvariablen und nicht statische Initialisierungsblöcke in der Reihenfolge der Deklaration in
  5. rest des Konstruktors.
3
Oh Chin Boon

So funktioniert Java. Wenn Sie ein untergeordnetes Objekt erstellen, wird der Superkonstruktor (implizit) aufgerufen.

2
anon

hier kann Ihr Test auf Ihre test1-Klasse erweitert werden, was bedeutet, dass Sie auf alle Testmethoden und -variablen in test1 zugreifen können. Beachten Sie, dass Sie nur dann auf eine Klassenmethode oder -variable zugreifen können, wenn Speicherplatz zugewiesen ist. Dazu benötigen Sie einen Konstruktor, entweder einen Standard- oder einen parametrisierten Parameter. Wenn der Compiler also feststellt, dass er eine Klasse erweitert, versucht er, die Klasse zu finden Superklasse-Konstruktor, damit Sie auf alle seine Methoden zugreifen können.

1
Akhil Vijayan

In einfachen Worten: Wenn die Superklasse einen Konstruktor parametrisiert hat, müssen Sie explizit Super (params) in der ersten Zeile Ihres Kindklassenkonstruktors aufrufen. Andernfalls werden alle Superklassenkonstruktoren implizit aufgerufen, bis die Objektklasse nicht erreicht wird.

1
Isham

Wenn ein Konstruktor einen Superklassenkonstruktor nicht explizit aufruft, fügt der Java-Compiler automatisch einen Aufruf des Konstruktors ohne Argumente der Superklasse ein. Wenn die Superklasse keinen Konstruktor ohne Argumente hat, wird ein Fehler bei der Kompilierung angezeigt Object verfügt über einen solchen Konstruktor. Wenn also Object die einzige Superklasse ist, gibt es kein Problem. "
(Quelle: https://docs.Oracle.com/javase/tutorial/Java/IandI/super.html )

1
Sameer Khanal

Der Basisklassenkonstruktor wird vor dem abgeleiteten Klassenkonstruktor aufgerufen. Dies ist sinnvoll, weil dadurch sichergestellt wird, dass die Basisklasse ordnungsgemäß erstellt wird, wenn der Konstruktor für die abgeleitete Klasse ausgeführt wird. Auf diese Weise können Sie einige Daten aus der Basisklasse während der Erstellung der abgeleiteten Klasse verwenden.

1
Ravi

Wie wir wissen, müssen Mitgliedsvariablen (Felder) einer Klasse vor dem Erstellen eines Objekts initialisiert werden, da diese Felder den Status des Objekts darstellen. Wenn diese Felder explizit nicht initialisiert werden, stellt der Compiler sie implizit als Standardwerte bereit, indem sie den no-argument-Standardkonstruktor aufruft. Aus diesem Grund ruft der Unterklassenkonstruktor den übergeordneten Klassenkonstruktor No-Argument auf, oder er wird implizit vom Compiler aufgerufen. Lokale Variablen werden vom Compiler nicht mit Standardwerten versorgt.

1
maneeshp626

Wenn Sie ein Objekt der Unterklasse erstellen, müssen alle in der Oberklasse definierten Memberfunktionen und Membervariablen berücksichtigt werden. Es kann ein Fall auftreten, in dem einige Membervariable in einigen der Superklassenkonstruktoren initialisiert werden kann. Wenn wir also ein Unterklassenobjekt erstellen, werden alle Konstruktoren im entsprechenden Vererbungsbaum von oben nach unten aufgerufen.

Insbesondere wenn eine Variable als protected definiert ist ist sie immer in der Unterklasse verfügbar, unabhängig davon, ob sich die Unterklasse im selben Paket befindet oder nicht . Wenn wir nun aus der Unterklasse eine Superklassenfunktion aufrufen, um den Wert dieser geschützten Variablen (die im Konstruktor der Superklasse initialisiert werden kann) zu drucken, müssen wir den korrekten initialisierten Wert erhalten. Daher werden alle Superklassenkonstruktoren aufgerufen.

Intern ruft Java in jedem Konstruktor super () auf. Jeder Unterklassenkonstruktor ruft seinen Superklassenkonstruktor mit super () auf, und daher werden sie in der untersten Art ausgeführt.

Hinweis: Funktionen können nicht die Variablen überschrieben werden. 

1
Aniket Thakur

Ich werde versuchen, dies aus einer anderen Perspektive zu beantworten. 

Angenommen, Java hat den Superkonstruktor nicht automatisch für Sie aufgerufen. Wenn Sie die Klasse erben, müssen Sie entweder den Superkonstruktor implizit aufrufen oder selbst neu schreiben. Dies erfordert, dass Sie über ein internes Wissen darüber verfügen, wie die Superklasse funktioniert, was schlecht ist. Es müsste auch Code neu geschrieben werden, was auch nicht gut ist. 

Ich bin damit einverstanden, dass der Aufruf des Superkonstruktors hinter den Kulissen etwas unintuitiv ist. Auf der anderen Seite bin ich nicht sicher, wie sie das auf eine intuitivere Weise hätten tun können. 

1
NL3294

Es gibt einen Standardaufruf super () in Ihren Standardkonstruktoren von Unterklassen.

 //Default constructor of subClass
    subClass() {
    super();
    }
1
Bhaskar

Die Unterklasse erbt Felder von ihrer Superklasse (n) und diesen Feldern haben , die erstellt/initialisiert werden sollen (das ist der übliche Zweck eines Konstruktors: Die Klassenmitglieder werden so initiiert, dass die Instanz wie erforderlich funktioniert. Wir wissen, dass einige Leute dies aber tun viel mehr Funktionalität in diesen schlechten Konstruktoren ...)

1
Andreas_D

Da Sie die Eigenschaften der Basisklasse in abgeleitete Klassen erben, kann es vorkommen, dass der Konstruktor für abgeleitete Klassen einige der Basisklassenvariablen benötigt, um ihre Variablen zu initialisieren. Zuerst müssen also Basisklassenvariablen und dann abgeleitete Klassenvariablen initialisiert werden. Aus diesem Grund ruft Java zuerst den Basisklassenkonstruktor und dann den abgeleiteten Klassenkonstruktor auf.

Und es macht auch keinen Sinn, die Kindklasse ohne die Elternklasse zu initialisieren.

1
user1923551

Der Konstruktor implementiert eine Logik, die das Objekt betriebsbereit macht. Object kann in privaten Feldern den Status state haben, sodass nur die Methoden seiner Klasse auf sie zugreifen können. Wenn Sie also möchten, dass die Instanz Ihrer Unterklasse nach dem Aufruf des Konstruktors wirklich einsatzbereit ist (d. H. Alle Funktionen einschließlich der von der Basisklasse geerbten Klasse sind OK), muss der Konstruktor der Basisklasse aufgerufen werden. 

Deshalb arbeitet das System so. 

Es wird automatisch der Standardkonstruktor der Basisklasse aufgerufen. Wenn Sie dies ändern möchten, müssen Sie den Konstruktor der Basisklasse explizit aufrufen, indem Sie super() in die erste Zeile des Konstruktors Ihrer Unterklasse schreiben.

1
AlexR

Der Konstruktor der Superklasse wird zuerst aufgerufen, da alle Methoden im Programm zuerst im Heap vorhanden sind und nach dem Kompilieren im Stapel gespeichert werden, wodurch der Superklassenkonstruktor zuerst aufgerufen wird.

1
Mukul Goyal

Elternausgänge zuerst !! Und wie in der realen Welt kann Child ohne die Eltern nicht existieren .. Daher ist es zunächst wichtig, Eltern (SuperClass) zu initialisieren, um Thrm in den Kinderklassen (Unterklasse) zu verwenden.

0
Shubham Soni