こんにちは、私はJavaが初めてです。実稼働ワーカークラスでこのエラーが発生しています。私のプロダクションワーカーコンストラクターは、別のコンストラクターを明示的に呼び出します。どうすればいいのかわかりません。
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;
}
}
知っているクラスのコンストラクタは、オブジェクトを作成します。そのため、コンストラクターにはクラスの適切な初期化コードが含まれている必要があります。ただし、別のクラスを拡張するクラスがある場合(「親」と呼びます)、そのクラスのコンストラクターには、定義による初期化に必要なすべてのコードを含めることはできません(たとえば、親のプライベートフィールドを定義できません)。そのため、クラスのコンストラクターは親のコンストラクターを呼び出す必要があります。明示的に呼び出さない場合は、デフォルトの親コンストラクターが呼び出されます(パラメーターはありません)。
したがって、あなたの場合、デフォルトのコンストラクタを親に実装するか、クラスのコンストラクタを直接呼び出すことができます。
他の人がすでに述べたように、Employee
クラスでデフォルトのコンストラクタpublic Employee(){}
を提供する必要があります。
何が起こるかというと、コンパイラーは、コンストラクターのないクラスに対して、引数のないデフォルトのコンストラクターを自動的に提供します。クラスに明示的なsuperclassがない場合、暗黙のスーパークラスObject
があり、には引数がありませんコンストラクター。この場合、クラスEmployee
でコンストラクターを宣言しているため、mustは引数なしのコンストラクターも提供します。
Employee
クラスは次のようになっているはずだと言いました:
クラスの従業員
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;
}
}
Java Oracleチュートリアル- クラスにコンストラクタを提供する )の章があります。これを最後まで読んで、何が起こっているかをより明確に理解してください。
ProductionWorker
はEmployee
を拡張するため、従業員のすべての機能を備えていると言われています。これを実現するために、Javaは自動的にsuper();
呼び出しを各コンストラクターの最初の行に配置します。手動で配置できますが、通常は必要ありません。 isが必要なのは、super();
の呼び出しが、従業員のコンストラクターにパラメーターがあるために自動的に配置できないためです。
Employee
クラスでデフォルトのコンストラクターを定義するか、ProductionWorkerのコンストラクターの最初の行でsuper('Erkan', 21, new Date());
を呼び出す必要があります。
親クラスに引数なしのコンストラクターがない場合は、親クラスコンストラクターの明示的な呼び出しが必要です。引数なしのコンストラクターを親クラスに追加するか、子クラスで親クラスコンストラクターを明示的に呼び出すことができます。
この問題は、コンストラクターをすぐに呼び出さないときにも発生する可能性があります。
したがって、これは動作します:
public Employee(String name, String number, Date date)
{
super(....)
}
しかし、これはしません:
public Employee(String name, String number, Date date)
{
// an example of *any* code running before you call super.
if (number < 5)
{
number++;
}
super(....)
}
2番目の例が失敗する理由は、Javaが暗黙的に呼び出そうとしているためです。
super(name,number,date)
コンストラクターの最初の行として....だからJavaは、コンストラクターで後からsuperの呼び出しが行われたことを認識しません。基本的にこれを実行しようとします。
public Employee(String name, String number, Date date)
{
super(name, number, date);
if (number < 5)
{
number++;
}
super(....)
}
そのため、解決策は非常に簡単です...super呼び出しの前にコードを置かないでください;-)への呼び出しの前に何かを初期化する必要がある場合super、別のコンストラクターで実行してから、古いコンストラクターを呼び出します...この例のように このStackOverflow postから取得 :
public class Foo
{
private int x;
public Foo()
{
this(1);
}
public Foo(int x)
{
this.x = x;
}
}
最近、私のcompラボでこの問題が発生しました。それは簡単で、エルカンはそれを正しく答えました。 super("the name of your subclass")
を置くだけで、問題に関連して-> super("ProductionWorker);
をsubclass'
コンストラクターの最初の行として配置します。