wake-up-neo.net

Standardkonstruktoren und Vererbung in Java

Ich habe eine Frage zu Standardkonstruktoren und Vererbung in Java. 

Wenn Sie eine Klasse schreiben und keinen Konstruktor enthalten, stellt Java im Allgemeinen automatisch einen Standardkonstruktor (einen Parameter ohne Parameter) bereit, der alle Instanzvariablen der Klasse (sofern vorhanden) mit einigen Standardwerten (0, null) initialisiert , oder falsch). Wenn Sie jedoch einen Konstruktor mit einigen Parametern schreiben und keinen Standardkonstruktor schreiben, stellt Java keinen Standardkonstruktor bereit. Meine Frage ist: Was ist der Fall bei Klassen, die von anderen Klassen erben? Wenn ich einen Konstruktor mit einigen Parametern schreibe, aber keinen Standardkonstruktor einsetze, erben sie den Standardkonstruktor der Oberklasse ?

50
user42155
  1. Wenn Sie keinen Konstruktor erstellen, wird der leere Standardkonstruktor automatisch erstellt .

  2. Wenn ein Konstruktor einen Super oder diesen Konstruktor nicht explizit als erste Anweisung aufruft, wird ein Aufruf von super () automatisch hinzugefügt .

Immer.

61
paulmurray

Konstruktoren werden nicht vererbt.

Die Initialisierung von Feldern wird auch von der virtuellen Maschine durchgeführt, nicht vom Standardkonstruktor. Der Standardkonstruktor ruft nur den Standardkonstruktor der Superklasse auf, und der Standardkonstruktor von Object ist leer. Das Gute an diesem Entwurf ist, dass es niemals möglich ist, auf nicht initialisierte Felder zuzugreifen.

52
starblue

Wenn Sie nicht super (...) verwenden, ruft ein Konstruktor den leeren Konstruktor seines übergeordneten Objekts auf.

Das erbt nicht, die Unterklassen erhalten nicht dieselben Konstruktoren mit denselben Argumenten. Sie können jedoch Konstruktoren hinzufügen, die einen der Konstruktoren der Superklasse aufrufen.

11
Peter Lawrey

Die Grundregel ist ein Aufruf (oder Aufruf) eines Konstruktors. Die erste Anweisung, die JVM ausführen muss, ist

Wenn Sie also eine Superklasse mit nur parametrisiertem Konstruktor und keinem Standardkonstruktor haben und die Basisklasse keinen expliziten Aufruf des parametrisierten Konstruktors der Superklasse hat, stellt JVM das super () bereit. Ein Aufruf, der einen Fehler auslöst, da für die Oberklasse kein Standardkonstruktor vorhanden ist. Daher geben wir entweder einen Standardkonstruktor in der Oberklasse an oder rufen explizit den parametrisierten Konstruktor der Oberklasse im Konstruktor der Basisklasse auf. Wenn wir den expliziten Aufruf geben, macht die JVM nicht die Mühe, die Zeile super () zu setzen. Der Aufruf des Konstruktors sollte die erste Anweisung der Methode sein, die (aufgrund unseres expliziten Aufrufs) nicht möglich ist.

6
Abhishek Nair

In Abschnitt 8.8.9 der Java-Sprachspezifikation wird detailliert beschrieben, was passiert:

Wenn eine Klasse keine Konstruktordeklarationen enthält, lautet der Standardkonstruktor implizit erklärt. Die Form des default-Konstruktors für eine Klasse der obersten Ebene, Mitgliedsklasse oder lokale Klasse lautet wie folgt:

  • Der Standardkonstruktor hat die gleiche Zugriffsmöglichkeit wie die Klasse (§6.6).
  • Der Standardkonstruktor hat keine formalen Parameter, außer in einem nicht privaten innere Member-Klasse, wobei der Standardkonstruktor implizit eine formale .__ deklariert. Parameter, der die unmittelbar einschließende Instanz der Klasse darstellt (§8.8.1, §15.9.2, §15.9.3).
  • Der Standardkonstruktor hat keine Throw-Klauseln.
  • Wenn die deklarierte Klasse die ursprüngliche Klasse Object ist, wird der Standardwert Konstruktor hat einen leeren Körper. Ansonsten ist der Standardkonstruktor einfach Ruft den Superklassenkonstruktor ohne Argumente auf.

Sie sehen, dass hier keine Vererbung stattfindet: Alles, was dazu gehört, ist die "Compiler-Magie" mit implizit deklariertem Standardkonstruktor. Die Spezifikation macht auch deutlich, dass der Standardkonstruktor nur dann hinzugefügt wird, wenn die Klasse überhaupt keine Konstruktoren enthält. Dies bedeutet, dass die Antwort auf Ihre Frage "Nein" lautet: Sobald Sie einer Klasse einen Konstruktor geben, wird der Zugriff auf den Standardkonstruktor der Klasse angezeigt Superklasse geht verloren.

5
dasblinkenlight

Wenn Sie einen Konstruktor angeben, generiert Java keinen leeren Standardkonstruktor. Ihre abgeleitete Klasse kann also nur Ihren Konstruktor aufrufen.

Der Standardkonstruktor initialisiert Ihre privaten Variablen nicht mit Standardwerten. Der Beweis ist, dass es möglich ist, eine Klasse zu schreiben, die keinen Standardkonstruktor hat und deren private Member mit Standardwerten initialisiert sind. Hier ist ein Beispiel:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}
3
potyl

Die Antwort auf Ihre Frage ist sehr einfach. Implizit (Invisible) ist die erste Anweisung in einem Konstruktor 'super ();' dh der Aufruf von super class ist kein Parameter-Konstruktor, bis Sie ihn explizit in etwas wie "this ();", "this (int)", "this (String)", "super (int)", "super (String)" ändern ) 'etc .' this (); ' ist der Konstruktor der aktuellen Klasse.

2
Ashish

Thumb-Regel ist, dass die Unterklasse jeden Konstruktor von der Basisklasse aus aufrufen sollte. Wenn Sie nicht über die Standardkonfiguration verfügen, rufen Sie die vorhandene Klasse von der Unterklasse an. Implementieren Sie ansonsten die leere Konstante in der Basisklasse, um das Kompilierungsproblem zu vermeiden

2
Muthu N

Wenn wir keinen Konstruktor erstellen, erstellt Java automatisch einen Standardkonstruktor. Wenn wir jedoch einen oder mehrere benutzerdefinierte Konstruktoren mit Argumenten erstellen, erstellt Java keine Standardkonstruktoren. Wenn wir einen oder mehrere Konstruktoren erstellen, werden Wenn Sie ein Objekt ohne Konstruktorargumente erstellen möchten, müssen Sie einen leeren Konstruktor deklarieren.

1
Thusitha

Jeder Konstruktor in einer Unterklasse ruft den Konstruktor ohne Argument (oder den Standardkonstruktor) der übergeordneten Klasse auf. Wenn Sie einen parametrisierten Konstruktor in der übergeordneten Klasse definieren, müssen Sie den übergeordneten Klassenkonstruktor explizit mit dem Schlüsselwort super aufrufen. Andernfalls wird der Kompilierungsfehler ausgegeben.

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Der obige Code wird den Kompilierungsfehler geben:

prog.Java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
    { 
    ^
  required: int,int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

Der obige Fehler ist aufgetreten, weil weder ein Argumentkonstruktor/Standardkonstruktor in der übergeordneten Klasse vorhanden ist, noch der parametrisierte Konstruktor aus der Unterklasse aufgerufen wird.

Um dies zu lösen, rufen Sie den parametrisierten Konstruktor wie folgt auf:

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        super(4, 5); // calling the parameterized constructor of parent class
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Ausgabe

base
derived

oder

definieren Sie einen Konstruktor ohne Argumente in der übergeordneten Klasse wie folgt:

class Alpha 
{ 
    Alpha(){

    }
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

ausgabe

derived 
0
Anmol Middha

Es wird ein Fehler beim Kompilieren auftreten, da der Compiler nach dem Standardkonstruktor sucht. Die Superklasse ist nicht vorhanden. Wenn nicht, ist dies ein Fehler. Das Programm kann nicht kompilieren.

0
Shubham Soni