web-dev-qa-db-fra.com

Java. Le super constructeur implicite Employee () n'est pas défini. Doit invoquer explicitement un autre constructeur

Bonjour, je suis nouveau à Java, je reçois cette erreur dans ma classe de travailleur de production. Mon constructeur d'ouvrier de production dit invoquer explicitement un autre constructeur. Je ne sais pas quoi faire?.

import Java.util.Date;

public class Employee
{
      private String name, number;
      private Date date;

      public Employee(String name, String number, Date date)
      {
            setName(name);
            setNumber(number);
            setDate(date);
      }

      public void setName(String n)
      {
            name = n;
      }
      public void setNumber(String n)
      {
            number = n;
            // you can check the format here for correctness
      }
      public void setDate(Date d)
      {
            date = d;
      }

      public String getName()
      {
            return name;
      }
      public String getNumber()
      {
            return number;
      }
      public Date getDate()
      {
            return date;
      }
}



public class ProductionWorker extends Employee
{
      private int shift;
      private double hourlyrate;
       // error is here (Implicit super constructor Employee() is undefined. Must explicitly invoke another constructor).
      public ProductionWorker(int shift, double hourlyrate)
      {
            setShift(shift);
            setHourlyPayRate(hourlyrate);
      }

      public void setShift(int s)
      {
            shift = s;
      }
      public void setHourlyPayRate(double rate)
      {
            hourlyrate = rate;
      }

      public int getShift()
      {
            return shift;
      }
      public double getHourlyPayRate()
      {
            return hourlyrate;
      }
}
25
user659658

Tout constructeur pour n'importe quelle classe comme vous le savez crée un objet. Ainsi, le constructeur doit contenir le code d'initialisation approprié pour sa classe. Mais si vous avez une classe qui en étend une autre (appelons-la "parent"), le constructeur de la classe ne peut pas contenir tout le code nécessaire pour l'initialisation par définition (par exemple, vous ne pouvez pas définir les champs privés du parent). C'est pourquoi le constructeur de la classe doit appeler le constructeur de son parent. Si vous ne l'appelez pas explicitement, le constructeur parent par défaut est appelé (sans aucun paramètre).

Donc, dans votre cas, vous pouvez implémenter le constructeur par défaut dans le parent ou appeler directement n'importe quel constructeur de la classe.

28
xappymah

Comme d'autres l'ont déjà mentionné, vous devez fournir un constructeur par défaut public Employee(){} dans votre classe Employee.

Ce qui se passe, c'est que le compilateur fournit automatiquement un constructeur par défaut sans argument pour toute classe sans constructeur. Si votre classe n'a pas de superclasse explicite, alors elle a une superclasse implicite de Object, qui a un constructeur sans argument . Dans ce cas, vous déclarez un constructeur dans votre classe Employee donc vous devez fournir également le constructeur sans argument.

Cela dit, la classe Employee devrait ressembler à ceci:

Votre employé de classe

import Java.util.Date;

public class Employee
{
      private String name, number;
      private Date date;

      public Employee(){} // No-argument Constructor

      public Employee(String name, String number, Date date)
      {
            setName(name);
            setNumber(number);
            setDate(date);
      }

      public void setName(String n)
      {
            name = n;
      }
      public void setNumber(String n)
      {
            number = n;
            // you can check the format here for correctness
      }
      public void setDate(Date d)
      {
            date = d;
      }

      public String getName()
      {
            return name;
      }
      public String getNumber()
      {
            return number;
      }
      public Date getDate()
      {
            return date;
      }
}

Voici le chapitre Java Tutoriel Oracle - Fournir des constructeurs pour vos classes . Parcourez-le et vous aurez une idée plus claire de ce qui se passe.

9
Bartzilla

ProductionWorker étend Employee, on dit donc qu'il a toutes les capacités d'un employé. Pour ce faire, Java place automatiquement un appel super(); dans la première ligne de chaque constructeur, vous pouvez le placer manuellement mais généralement ce n'est pas nécessaire. Dans votre cas, il est nécessaire parce que l'appel à super(); ne peut pas être placé automatiquement car le constructeur de l'employé a des paramètres.

Vous devez soit définir un constructeur par défaut dans votre classe Employee, soit appeler super('Erkan', 21, new Date()); dans la première ligne du constructeur dans ProductionWorker.

3
Erkan Haspulat

Un appel explicite à un constructeur de classe parent est requis chaque fois que la classe parent n'a pas de constructeur sans argument. Vous pouvez soit ajouter un constructeur sans argument à la classe parent, soit appeler explicitement le constructeur de la classe parent dans votre classe enfant.

2
Isaac Truett

Ce problème peut également survenir lorsque votre constructeur n'appelle pas immédiatement super.

Cela fonctionnera donc:

  public Employee(String name, String number, Date date)
  {
    super(....)
  }

Mais cela ne va pas:

  public Employee(String name, String number, Date date)
  {
    // an example of *any* code running before you call super.
    if (number < 5)
    {
       number++;
    }

    super(....)
  }

Le deuxième exemple échoue parce que Java essaie d'appeler implicitement

super(name,number,date)

comme première ligne de votre constructeur .... Donc Java ne voit pas que vous avez un appel à super en cours plus tard dans le constructeur. Il essaie essentiellement de le faire:

  public Employee(String name, String number, Date date)
  {
    super(name, number, date);

    if (number < 5)
    {
       number++;
    }

    super(....)
  }

La solution est donc assez simple ... Ne mettez pas le code avant votre super appel ;-) Si vous devez initialiser quelque chose avant l'appel à super, faites-le dans un autre constructeur, puis appelez l'ancien constructeur ... Comme dans cet exemple tiré de ce post StackOverflow :

public class Foo
{
    private int x;

    public Foo()
    {
        this(1);
    }

    public Foo(int x)
    {
        this.x = x;
    }
}
0
Brad Parks

J'ai eu ce problème récemment dans mon laboratoire de comp. C'est simple et Erkan a répondu correctement. Mettez simplement super("the name of your subclass") Donc, par rapport à votre problème -> super("ProductionWorker); comme première ligne de votre subclass' constructeur.

0
Brent Ivey