Suche…


Einführung

Konstruktoren in Java sind zwar nicht erforderlich, aber vom Compiler erkannte Methoden, um bestimmte Werte für die Klasse zu instanziieren, die für die Rolle des Objekts wesentlich sein können. In diesem Thema wird die ordnungsgemäße Verwendung von Java-Klassenkonstruktoren veranschaulicht.

Bemerkungen

In der Java-Sprachspezifikation wird ausführlich über die genaue Natur der Konstruktorsemantik gesprochen. Sie können in JLS §8.8 gefunden werden

Standardkonstruktor

Der "Standard" für Konstruktoren ist, dass sie keine Argumente haben. Wenn Sie keinen Konstruktor angeben, generiert der Compiler einen Standardkonstruktor für Sie.
Dies bedeutet, dass die folgenden zwei Ausschnitte semantisch äquivalent sind:

public class TestClass {
    private String test;
}
public class TestClass {
    private String test;
    public TestClass() {

    }
}

Die Sichtbarkeit des Standardkonstruktors entspricht der Sichtbarkeit der Klasse. Daher hat eine Klasse, die als paket-privat definiert wurde, einen paket-privaten Standardkonstruktor

Wenn Sie jedoch keinen Standardkonstruktor verwenden, generiert der Compiler keinen Standardkonstruktor für Sie. Also sind diese nicht gleichwertig:

public class TestClass {
    private String test;
    public TestClass(String arg) {
    }
}
public class TestClass {
    private String test;
    public TestClass() {
    }
    public TestClass(String arg) {
    }
}

Beachten Sie, dass der generierte Konstruktor keine nicht standardisierte Initialisierung durchführt. Das bedeutet, dass alle Felder Ihrer Klasse ihren Standardwert haben, sofern sie keinen Initialisierer haben.

public class TestClass {

    private String testData;

    public TestClass() {
        testData = "Test"
    }
}

Konstruktoren werden so genannt:

TestClass testClass = new TestClass();

Konstruktor mit Argumenten

Konstruktoren können mit beliebigen Argumenten erstellt werden.

public class TestClass {

    private String testData;

    public TestClass(String testData) {
        this.testData = testData;
    }
}

So genannt:

TestClass testClass = new TestClass("Test Data");

Eine Klasse kann mehrere Konstruktoren mit unterschiedlichen Signaturen haben. Um Konstruktoraufrufe zu verketten (rufen Sie beim Instanziieren einen anderen Konstruktor derselben Klasse an), verwenden Sie this() .

public class TestClass {

    private String testData;

    public TestClass(String testData) {
        this.testData = testData;
    }

    public TestClass() {
        this("Test"); // testData defaults to "Test"
    }
}

So genannt:

TestClass testClass1 = new TestClass("Test Data");
TestClass testClass2 = new TestClass();

Rufen Sie den übergeordneten Konstruktor auf

Angenommen, Sie haben eine Elternklasse und eine Kindklasse. Um eine Child-Instanz zu erstellen, muss immer ein Parent-Konstruktor beim ersten Start des Child-Konstruktors ausgeführt werden. Wir können den gewünschten super(...) Konstruktor auswählen, indem wir super(...) mit den entsprechenden Argumenten explizit als unsere erste Child-Konstruktoranweisung aufrufen. Dadurch sparen Sie Zeit, indem Sie den Konstruktor der übergeordneten Klassen wiederverwenden, anstatt den gleichen Code im Konstruktor der untergeordneten Klassen neu zu schreiben.

Ohne super(...) Methode:

(implizit wird die no-args-Version super() als unsichtbar bezeichnet.)

class Parent {
    private String name;
    private int age;
    
    public Parent() {} // necessary because we call super() without arguments
    
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}

// This does not even compile, because name and age are private,
// making them invisible even to the child class.
class Child extends Parent {
    public Child() {
        // compiler implicitly calls super() here
        name = "John";
        age = 42;
    }
}

Mit super() Methode:

class Parent {
    private String name;
    private int age;
    public Parent(String tName, int tAge) {
        name = tName;
        age = tAge;
    }
}

class Child extends Parent {
    public Child() {
        super("John", 42);   // explicit super-call
    }
}

Anmerkung: Aufrufe an einen anderen Konstruktor (Verkettung) oder den Super-Konstruktor MÜSSEN die erste Anweisung innerhalb des Konstruktors sein.

Wenn Sie den super(...) explizit aufrufen, muss ein übereinstimmender übergeordneter Konstruktor vorhanden sein (das ist unkompliziert, nicht wahr?).

Wenn Sie keinen super(...) explizit aufrufen, muss Ihre übergeordnete Klasse über einen no-args-Konstruktor verfügen. Dieser kann entweder explizit geschrieben oder vom Compiler als Standardwert erstellt werden, wenn die übergeordnete Klasse keine Angaben macht irgendein Konstruktor.

class Parent{
    public Parent(String tName, int tAge) {}
}

class Child extends Parent{
    public Child(){}
}

Die Klasse Parent hat keinen Standardkonstruktor, daher kann der Compiler nicht super im Child-Konstruktor hinzufügen. Dieser Code wird nicht kompiliert. Sie müssen die Konstruktoren ändern, um auf beide Seiten zu passen, oder Ihren eigenen super Aufruf schreiben, wie folgt:

class Child extends Parent{
    public Child(){
          super("",0);
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow