Java-fout: impliciete superconstructor is niet gedefinieerd voor standaardconstructor

Ik heb een eenvoudige Java-code die er qua structuur ongeveer zo uitziet:

abstract public class BaseClass {
    String someString;
    public BaseClass(String someString) {
        this.someString = someString;
    }
    abstract public String getName();
}
public class ACSubClass extends BaseClass {
    public ASubClass(String someString) {
        super(someString);
    }
    public String getName() {
        return "name value for ASubClass";
    }
}

Ik zal een flink aantal subklassen van BaseClasshebben, die elk de getName()-methode op hun eigen manier implementeren (patroon voor sjabloonmethode).

Dit werkt goed, maar ik hou er niet van om de redundante constructor in de subklassen te hebben. Het is meer typen en moeilijk te onderhouden. Als ik de methodehandtekening van de BaseClass-constructor zou wijzigen, zou ik alle subklassen moeten veranderen.

Als ik de constructor uit de subklassen verwijder, krijg ik deze compileerfout:

Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor

Is wat ik probeer te doen mogelijk?


Antwoord 1, autoriteit 100%

Je krijgt deze foutmelding omdat een klasse die geen constructor heeft een defaultconstructor heeft, die geen argumenten bevat en gelijk is aan de volgende code:

public ACSubClass() {
    super();
}

Aangezien uw BaseClass echter een constructor declareert (en daarom niet de standaard no-arg-constructor heeft die de compiler anders zou bieden), is dit illegaal – een klasse die BaseClass uitbreidt, kan super();omdat er geen constructor zonder argumenten is in BaseClass.

Dit is waarschijnlijk een beetje contra-intuïtief omdat je zou kunnen denken dat een subklasse automatisch een constructor heeft die de basisklasse heeft.

De eenvoudigste manier om dit te omzeilen is dat de basisklasse geen constructor declareert (en dus de standaard no-arg-constructor heeft) of een gedeclareerde no-arg-constructor heeft (op zichzelf of naast andere constructors). Maar vaak kan deze benadering niet worden toegepast – omdat je alle argumenten nodig hebt die aan de constructor worden doorgegeven om een ​​legitieme instantie van de klasse te construeren.


Antwoord 2, autoriteit 34%

Voor degenen die Googlen voor deze fout en hier aankomen: er kan een andere reden zijn om deze te ontvangen. Eclipse geeft deze foutmelding als je een projectconfiguratie hebt – systeemconfiguratie komt niet overeen.

Als u bijvoorbeeld een Java 1.7-project naar Eclipse importeert en 1.7 niet correct is ingesteld, krijgt u deze foutmelding. Dan kun je ofwel naar Project - Preference - Java - Compilergaan en switch to 1.6 or earlier; of ga naar Window - Preferences - Java - Installed JREsen voeg uw JRE 1.7-installatie toe/repareer deze.


Antwoord 3, autoriteit 5%

Het is mogelijk, maar niet zoals jij het hebt.

Je moet een no-args-constructor aan de basisklasse toevoegen en dat is alles!

public abstract class A {
    private String name;
    public A(){
        this.name = getName();
    }
    public abstract String getName();
    public String toString(){
        return "simple class name: " + this.getClass().getSimpleName() + " name:\"" + this.name + "\"";
    }
}
class B extends A {
    public String getName(){
        return "my name is B";
    }
    public static void main( String [] args ) {
        System.out.println( new C() );
    }
}
class C extends A {
    public String getName() {
        return "Zee";
    }
}

Als u geen constructor ( any ) aan een klasse toevoegt, voegt de compiler de standaard no arg-constructor voor u toe.

Als de standaard no arg super(); en aangezien je het niet in de superklasse hebt, krijg je die foutmelding.

Dat is ongeveer de vraag die het zelf is.

Nu, uitbreiding van het antwoord:

Beteken je dat het creëren van een subklasse (gedrag) om verschillende een andere waarde (gegevens) op te geven, geen zin ?? !!! Ik hoop dat je het doet.

Als het enige dat wijzigingen is de “naam” is, is een enkele klasse parametriseerd genoeg!

Dus je hebt dit niet nodig:

MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");

of

MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();

Wanneer u dit kunt schrijven:

MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");

Als ik de handtekening van de methode van de Baseclass-constructor zou wijzigen, zou ik alle subklassen moeten veranderen.

Nou, daarom is erfacturatie het artefact dat hoge koppeling creëert, die ongewenst is in OO-systemen. Het moet worden vermeden en misschien vervangen door samenstelling.

Denk aan als je ze echt echt nodig hebt als subklasse. Daarom zie je heel vaak geïnstalleerd interfaces:

public interface NameAware {
     public String getName();
 }
 class A implements NameAware ...
 class B implements NameAware ...
 class C ... etc. 

Hier kunnen B en C hebben geërfd van een die een zeer hoge koppeling onder hen zou hebben gecreëerd door interfaces te gebruiken, waarbij de koppeling wordt verminderd, als een besluit dat het niet langer “nameAware” zal zijn, zullen de andere klassen niet braken.

Natuurlijk, als u het gedrag wilt hergebruiken, werkt dit niet.


Antwoord 4, Autoriteit 3%

U kunt deze fout ook krijgen wanneer JRE niet is ingesteld. Als dit het geval is, probeer het JRE SYSTEEMBIBIERS toe aan uw project.

Onder Eclipse IDE:

  1. Open menu Project – & GT; Eigenschappen , of klik met de rechtermuisknop op uw project in PAKKET EXPLORER en kies Eigenschappen (ALT + ENTER op Windows, Command + I op Mac)
  2. Klik op Java Build Path Dan Bibliotheken Tab
  3. Kies MODULEPATH of ClassPath en druk op Bibliotheek toevoegen … -knop
  4. Selecteer JRE System Library Klik vervolgens op
  5. Houd Werkruimte Standaard JRE Geselecteerd (u kunt ook een andere optie nemen) en klik op
  6. Druk tenslotte op Toepassen en sluiten .

Antwoord 5

Nog een manier is call super () met het vereiste argument als een eerste verklaring in afgeleide klassenconstructeur.

public class Sup {
    public Sup(String s) { ...}
}
public class Sub extends Sup {
    public Sub() { super("hello"); .. }
}

Antwoord 6

Ik heb het probleem als volgt opgelost:

  1. Klik op het project.
  2. Klik op Eigenschappen & GT; Java Build Path & GT; Bibliotheek & GT; JRE System Library & GT; Bewerken
  3. Selecteer standaardsysteem JRE en FINISH
  4. Toepassen en sluiten.

Antwoord 7

Eclipse geeft deze foutmelding als u geen oproep hebt aan Super Class Constructor als eerste verklaring in Subclass Constructor.


Antwoord 8

Sorry voor necroposting, maar kreeg dit probleem gewoon vandaag. Voor iedereen die ook met dit probleem wordt geconfronteerd – een van de mogelijke redenen – belt u niet superbij de eerste methode. Ten tweede, derde en andere lijnen vuren deze fout. Oproep van Super moet zeer eerste oproep zijn in uw methode. In dit geval is alles goed.


Antwoord 9

Kort antwoord:
Voeg een constructor toe zonder argument in basis / ouder / superklasse. I.E bijvoorbeeld,

       class Parent{
    String name;
    int age;
    String occupation;
            //empty constructor
            public Parent(){
        }
    public Parent(String name, int age, String employment){
    this.name = name;
    this.age = age;
    this.occupation = employment;
    }
}

// U kunt eventuele aanvullende constructeurs hebben als u wenst dat AKA Constructor-overbelasting hier in de moederklasse is.

Als een superklasse niet de no-argument-constructor heeft, krijgt u de COMPILE-TIME-fout. Object heeft zo’n constructeur, dus als het object een alleen superklasse is, is er geen probleem.

// Laten we dan erven

   class Child extends Parent{
              Child(String name, int age){
this.name = name;
this.age = age;
    }
    }

Met Super () wordt een superklasse no-argument-constructeur gebeld en met super (parameterlijst), een superklasse-constructeur met de overeenkomende parameterlijst wordt genoemd.


Antwoord 10

Hier is eenvoudig voorbeeld

public class A {
    public A(int i){
       //
    }
 }
class B extends A {
    public B(int i){
      super(i);
    }
  }

Antwoord 11

U kunt deze fout oplossen door een argumentloze constructor aan de basisklasse (zoals hieronder getoond) toe te voegen.

Cheers.

abstract public class BaseClass {
        // ADD AN ARGUMENTLESS CONSTRUCTOR TO THE BASE CLASS
        public BaseClass(){
        }
        String someString;
        public BaseClass(String someString) {
            this.someString = someString;
        }
        abstract public String getName();
    }
public class ACSubClass extends BaseClass {
    public ASubClass(String someString) {
        super(someString);
    }
    public String getName() {
        return "name value for ASubClass";
    }
}

Antwoord 12

Ik had deze fout en heeft het vastgesteld door een gooide uitzondering van naast de methode te verwijderen in een try / pingblok

Bijvoorbeeld:
Van:

public static HashMap<String, String> getMap() throws SQLException
{
}

naar:

public static Hashmap<String,String> getMap()
{
  try{
  }catch(SQLException)
  { 
  }
}

Other episodes