这是可能的,但并非您拥有它的方式。
您必须在基类中添加一个无参数的构造函数,仅此而已!
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)时,编译器将为您添加默认的no arg构造函数。
当默认时,没有arg调用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耦合的人工产物的原因,这在OO系统中是不可取的。应该避免使用它,也许应该用合成代替。
考虑一下是否真的需要它们作为子类。这就是为什么您经常看到使用insted的接口的原因:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
在这里B和C可以从A继承而来,这将在它们之间创建一个非常高的耦合,通过使用接口,耦合将减少,如果A决定不再是“ NameAware”,则其他类将不会中断。
当然,如果您想重用行为,则将不起作用。