java构造函数未定义_Java错误:默认构造函数未定义隐式超级构造函数

当Java类扩展了一个带有指定构造函数的抽象基类时,如果没有提供默认构造函数,编译器会报错。这是因为子类在没有显式构造函数时,会尝试调用基类的无参构造函数,但基类没有这样的构造函数。解决办法是在基类中添加无参构造函数,或者确保子类都有对应的构造函数。此外,该问题也可能与项目配置(如JRE版本设置)有关。
摘要由CSDN通过智能技术生成

问题

我有一些简单的Java代码,在其结构中看起来与此类似:

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";

}

}

我将有很多子类BaseClass,每个子类以自己的方式实现getName()方法(template method pattern)。

这很好用,但我不喜欢在子类中使用冗余构造函数。打字更多,难以维护。如果我要更改BaseClassconstructor的方法签名,我将不得不更改所有子类。

当我从子类中删除构造函数时,我得到了这个编译时错误:

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

我正在尝试做什么?

#1 热门回答(140 赞)

你收到此错误,因为没有构造函数的类具有a默认值constructor,它是无参数且等效于以下代码:

public ACSubClass() {

super();

}

但是,由于你的BaseClass声明了一个构造函数(因此没有编译器可能提供的默认的no-arg构造函数)这是非法的 - 扩展BaseClass的类不能调用super();,因为没有无参数构造函数BaseClass的。

这可能有点违反直觉,因为你可能认为子类自动拥有基类具有的任何构造函数。

最简单的方法是让基类不声明构造函数(因此具有默认的无参数构造函数)或具有声明的无参数构造函数(无论是单独使用还是与任何其他构造函数一起)。但是通常不能应用这种方法 - 因为你需要将任何参数传递给构造函数来构造类的合法实例。

#2 热门回答(42 赞)

对于那些谷歌这个错误并到达这里的人:可能有另一个原因接收它。当你进行项目设置时,Eclipse会出现此错误 - 系统配置不匹配。

例如,如果你将Java 1.7项目导入Eclipse并且没有正确设置1.7,那么你将收到此错误。然后你可以去Project - Preference - Java - Compiler和switch to 1.6 or earlier;或者转到Window - Preferences - Java - Installed JREs并添加/修复你的JRE 1.7安装。

#3 热门回答(7 赞)

这是有可能的,但不是你的方式。

你必须在基类中添加一个no-args构造函数,就是这样!

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),编译器会为你添加缺省的无参数构造函数。

当defualt没有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",其他类将不会破坏。

当然,如果你想重用行为,这将无法工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值