それは可能ですが、あなたのやり方ではありません。
基本クラスに引数なしのコンストラクターを追加する必要がありますが、それだけです!
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";
}
}
クラスにコンストラクター(any)を追加しない場合、コンパイラーはデフォルトの引数なしのコンストラクターを追加します。
デフォルトでは、super()への引数呼び出しはありません。そして、あなたはスーパークラスにそれを持っていないので、あなたはそのエラーメッセージを受け取ります。
それはそれ自体の問題についてです。
さて、答えを広げます:
別の異なる値(データ)を指定するサブクラス(動作)を作成しても意味がないことをご存知ですか?!!! よろしくお願いします。
変更されているのが「名前」だけの場合、パラメータ化された単一のクラスで十分です。
したがって、これは必要ありません。
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
または
MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
あなたがこれを書くことができるとき:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
BaseClassコンストラクタのメソッドシグネチャを変更する場合、すべてのサブクラスを変更する必要があります。
それが継承がオブジェクト指向システムで望ましくないHIGHカップリングを作成するアーティファクトである理由です。それは避けられるべきであり、おそらく組成物で置き換えられるべきです。
サブクラスとして本当に必要かどうか考えてください。そのため、インターフェースがinstedで使用されることがよくあります。
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
ここで、BとCはAから継承している可能性があり、Aから非常に高いカップリングを作成します。インターフェースを使用することにより、カップリングは減少します。
もちろん、振る舞いを再利用したい場合、これは機能しません。