Java错误:隐式超级构造函数未定义为默认构造函数
我有一个简单的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"; } }
我将有不lessBaseClass
子类,每个都以自己的方式实现getName()
方法( 模板方法模式 )。
这工作得很好,但我不喜欢在子类中有冗余的构造函数。 input更多,难以维护。 如果我要改变BaseClass
构造函数的方法签名,我将不得不改变所有的子类。
当我从子类中移除构造函数时,我得到这个编译时错误:
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
我正在尝试做什么?
你得到这个错误是因为一个没有构造函数的类有一个默认的构造函数,这个构造函数是无参数的,并且等价于下面的代码:
public ACSubClass() { super(); }
但是,由于你的BaseClass声明了一个构造函数(因此没有默认的,编译器会提供的no-arg构造函数),这是非法的 – 扩展BaseClass的类不能调用super();
因为在BaseClass中没有没有参数的构造函数。
这可能有点反直觉,因为你可能认为子类自动具有基类所具有的构造函数。
最简单的方法是基类不声明一个构造函数(因此有默认的无参数构造函数),或者有一个声明的无参数构造函数(自己或者任何其他的构造函数)。 但是通常这种方法不能应用 – 因为你需要传递给构造函数的任何参数来构造类的合法实例。
对于那些Google出现此错误并到达此处的用户,可能有另一个接收该错误的原因。 当你有项目设置 – 系统configuration不匹配时,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安装。
这是可能的,但不是你拥有它的方式。
你必须添加一个无参数构造函数的基类,就是这样!
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"; } }
当你不添加一个构造函数(任何)到一个类,编译器为你添加默认的无arg构造器。
当defualt没有arg调用super(); 而且由于你没有在超类中得到这个错误信息。
这是关于它自己的问题。
现在,扩大答案:
你知道创build一个子类(行为)来指定不同的值(数据)是没有意义的! 我希望你会。
如果唯一的变化是“名称”,那么参数化的单个类就足够了!
所以你不需要这个:
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构造函数的方法签名,我将不得不改变所有的子类。
那么这就是为什么inheritance是产生高耦合的人为因素,这在OO系统中是不可取的。 应该避免,也许用组成来代替。
想想你是否真的需要他们作为子类。 这就是为什么你经常看到使用insted的界面:
public interface NameAware { public String getName(); } class A implements NameAware ... class B implements NameAware ... class C ... etc.
这里B和C可以从Ainheritance下来,它们之间会产生一个非常高的耦合,通过使用接口来减less耦合,如果A决定不再是“NameAware”,其他类将不会中断。
当然,如果你想重用行为,这是行不通的。
你的BaseClass需要一个someString来传递一个。
尝试这个:
abstract public class BaseClass { String someString; public BaseClass(String someString) { this.someString = someString; } abstract public String getName(); } public class ACSubClass extends BaseClass { public ASubClass() { super("someString"); // or a meaningfull value, same as getName()? } public String getName() { return "name value for ASubClass"; } }
要么
abstract public class BaseClass { String someString; protected BaseClass() { // for subclasses this.someString = null; // or a meaningfull value } public BaseClass(String someString) { this.someString = someString; } abstract public String getName(); } public class ACSubClass extends BaseClass { public String getName() { return "name value for ASubClass"; } }
另一种方法是使用必要的参数作为派生类构造函数中的第一个语句调用super()。
public class Sup { public Sup(String s) { ...} } public class Sub extends Sup { public Sub() { super("hello"); .. } }
如果您没有调用超类构造函数作为子类构造函数中的第一条语句,那么Eclipse会给出这个错误。
这个错误是由于JRE没有设置,所以请按照下列步骤操作:
1.右键单击project – > Properties – > Java Build Path – > Click Libraries选项卡
2.单击添加库
3.selectJRE系统库 – >单击下一步
4.select工作区默认jre或备用安装的jre
5.点击完成
您可以通过向基类添加无自variables构造函数来解决此错误(如下所示)。
干杯。
abstract public class BaseClass { // ADD AN ARGUMENTLESS CONSTRUCTOR TO THE BASE CLASS public 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"; } }
我有这个错误,并通过从方法旁边抛出一个抛出的exception来修复它try / catch块
例如:FROM:
public static HashMap<String, String> getMap() throws SQLException { }
至:
public static Hashmap<String,String> getMap() { try{ }catch(SQLException) { } }