2016-06-22 10 views
-1

In diesem Beispiel habe ich eine Unterklasse mit einem leeren Konstruktor. In der Oberklasse sind zwei Konstruktoren vorgesehen. Wenn ich das main in dem Code unten ausführe, stellt es sich heraus, dass es "ich bin der Superkonstruktor ohne Parameter" druckt. Meine Frage ist, warum der Compiler den leeren Konstruktor in der Unterklasse ignoriert? Wenn ich diese "Ignoranz" akzeptieren kann, dann verstehe ich, dass der Compiler den Standardkonstruktor der Unterklasse ausführt, der in diesem Fall der in der Oberklasse ohne Parameter ist. Hier ist die Unterklasse:Warum wird der (Super-) Standardkonstruktor anstelle eines leeren Konstruktors aufgerufen?

package extendisevil; 

public class SubConstructorInherit extends ConstructorInherit { 

    public SubConstructorInherit(String param) { 

    } 

    public static void main(String[] args) { 

    SubConstructorInherit obj = new SubConstructorInherit("valami"); 

    } 
} 

Und hier ist der Super:

package extendisevil; 

public class ConstructorInherit { 

    public ConstructorInherit(String name) { 
    System.out.println("I am the super constructor with String parameter: " + name); 
    } 

    public ConstructorInherit() { 
    System.out.println("I am the super constructor without parameter."); 
    } 

} 

Vielen Dank für Ihre Hilfe!

Antwort

7

Java ignoriert den Konstruktor der Unterklasse nicht, Java ruft es auf. Allerdings muss Java auch jede Superklasse konstruieren, und da Sie keinen bestimmten Superkonstruktor in Ihrem Unterklassenkonstruktor aufrufen, verwendet Java standardmäßig nur den Konstruktor no-arg. Wenn Sie einen anderen Konstruktor als die nicht-arg Konstruktor in der Eltern-Klasse aufrufen möchten, können Sie dies tun, indem super(/* args */); Aufruf, hat dies obwohl die erste Anweisung in Ihrem Konstruktor sein:

class Parent { 
    Parent() { 
     System.out.println("Parent()"); 
    } 
    Parent(String name) { 
     System.out.println("Parent(String): " + name); 
    } 
} 

class Child extends Parent { 
    Child() { 
     //calls "super()" implicitly as we don't call a constructor of Parent ourselfs 
     System.out.println("Child()"); 
    } 

    Child(String name) { 
     super(name); //we explicitly call a super-constructor 
     System.out.println("Child(String): " + name); 
    } 
} 

new Child(); 
new Child("A Name"); 

Drucke:

Parent() 
Child() 
Parent(String): A Name 
Child(String): A Name 

Wenn eine Klasse einen nicht-arg Konstruktor nicht zur Verfügung stellt, sondern einen Konstruktor mit Argumenten, ein Subklassen Konstruktor explizit Aufruf einer des gegebenen Konstrukteurs.

+0

Ich bin hier pingelig, aber wir sollten den Begriff 'default constructor' in diesem Fall nicht verwenden, ein besserer Name ist' no-arg constructor'. Der Grund dafür, 'default constructor' ist der spezifische Name für die automatisch generierten no-arg Konstruktorklassen, die in Abwesenheit expliziter Konstruktoren erhalten werden. – biziclop

+0

Sie haben Recht, bearbeitet es. – tkausl

+0

Vielleicht kristallisiert die Verwendung von implizit versus explizit die Erklärung. – Grayson

1

Die Tatsache, dass die Oberklasse eine Parameterliste mit den gleichen Typen hat, ist irrelevant - was ist, wenn die an die Unterklasse übergebene Zeichenfolge eine völlig andere Bedeutung hat als die an die Oberklasse übergebene Zeichenfolge? (Es ist nicht klar, warum name und param das gleiche bedeuten)

Wenn Sie einen bestimmten Nicht-Null-Arg-Konstruktor aufgerufen werden müssen, ist es besser, dass Sie explizit die Parameter an den Superkonstruktor übergeben müssen (auf Kosten einiger weiterer Schlüsselstriche), anstatt fälschlicherweise anzunehmen, dass ein bestimmter ctor aufgerufen werden sollte.

Verwandte Themen