Java错误:默认构造函数未定义隐式超级构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1197634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java error: Implicit super constructor is undefined for default constructor
提问by Joel
I have a some simple Java code that looks similar to this in its structure:
我有一些简单的 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";
}
}
I will have quite a few subclasses of BaseClass
, each implementing the getName()
method in its own way (template method pattern).
我将有很多子类BaseClass
,每个子类都getName()
以自己的方式实现方法(模板方法模式)。
This works well, but I don't like having the redundant constructor in the subclasses. It's more to type and it is difficult to maintain. If I were to change the method signature of the BaseClass
constructor, I would have to change all the subclasses.
这很有效,但我不喜欢在子类中使用冗余构造函数。打字多,维护困难。如果要更改BaseClass
构造函数的方法签名,则必须更改所有子类。
When I remove the constructor from the subclasses, I get this compile-time error:
当我从子类中删除构造函数时,出现此编译时错误:
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
Implicit super constructor BaseClass() is undefined for default constructor. Must define an explicit constructor
Is what I am trying to do possible?
我正在尝试做的可能吗?
采纳答案by matt b
You get this error because a class which has no constructor has a defaultconstructor, which is argument-less and is equivalent to the following code:
之所以会出现此错误,是因为没有构造函数的类具有默认构造函数,该构造函数是无参数的,等效于以下代码:
public ACSubClass() {
super();
}
However since your BaseClass declares a constructor (and therefore doesn't have the default, no-arg constructor that the compiler would otherwise provide) this is illegal - a class that extends BaseClass can't call super();
because there is not a no-argument constructor in BaseClass.
但是,由于您的 BaseClass 声明了一个构造函数(因此没有编译器本来会提供的默认无参数构造函数),这是非法的 - 无法调用扩展 BaseClass 的类,super();
因为没有无参数构造函数在基类中。
This is probably a little counter-intuitive because you might think that a subclass automatically has any constructor that the base class has.
这可能有点违反直觉,因为您可能认为子类自动具有基类具有的任何构造函数。
The simplest way around this is for the base class to not declare a constructor (and thus have the default, no-arg constructor) or have a declared no-arg constructor (either by itself or alongside any other constructors). But often this approach can't be applied - because you need whatever arguments are being passed into the constructor to construct a legit instance of the class.
解决此问题的最简单方法是让基类不声明构造函数(因此具有默认的无参数构造函数)或声明的无参数构造函数(单独或与任何其他构造函数一起)。但通常这种方法不能应用 - 因为您需要将任何参数传递给构造函数来构造类的合法实例。
回答by OscarRyz
It is possible but not the way you have it.
这是可能的,但不是你拥有它的方式。
You have to add a no-args constructor to the base class and that's it!
您必须向基类添加一个无参数构造函数,仅此而已!
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";
}
}
When you don't add a constructor ( any ) to a class the compiler add the default no arg contructor for you.
当您不向类添加构造函数( any )时,编译器会为您添加默认的 no arg 构造函数。
When the defualt no arg calls to super(); and since you don't have it in the super class you get that error message.
当默认没有 arg 调用 super(); 并且由于您在超类中没有它,您会收到该错误消息。
That's about the question it self.
那是关于它自己的问题。
Now, expanding the answer:
现在,扩展答案:
Are you aware that creating a subclass ( behavior ) to specify different a different value ( data ) makes no sense??!!! I hope you do.
您是否知道创建子类(行为)来指定不同的值(数据)是没有意义的??!!!我希望你会。
If the only thing that is changes is the "name" then a single class parametrized is enough!
如果唯一改变的是“名称”,那么参数化的单个类就足够了!
So you don't need this:
所以你不需要这个:
MyClass a = new A("A");
MyClass b = new B("B");
MyClass c = new C("C");
MyClass d = new D("D");
or
或者
MyClass a = new A(); // internally setting "A" "B", "C" etc.
MyClass b = new B();
MyClass c = new C();
MyClass d = new D();
When you can write this:
当你可以这样写时:
MyClass a = new MyClass("A");
MyClass b = new MyClass("B");
MyClass c = new MyClass("C");
MyClass d = new MyClass("D");
If I were to change the method signature of the BaseClass constructor, I would have to change all the subclasses.
如果要更改 BaseClass 构造函数的方法签名,则必须更改所有子类。
Well that's why inheritance is the artifact that creates HIGH coupling, which is undesirable in OO systems. It should be avoided and perhaps replaced with composition.
嗯,这就是为什么继承是创建高耦合的工件,这在 OO 系统中是不可取的。应该避免它,也许可以用组合来代替。
Think if you really really need them as subclass. That's why you see very often interfaces used insted:
想想你是否真的需要它们作为子类。这就是为什么你经常看到使用 insted 的接口:
public interface NameAware {
public String getName();
}
class A implements NameAware ...
class B implements NameAware ...
class C ... etc.
Here B and C could have inherited from A which would have created a very HIGH coupling among them, by using interfaces the coupling is reduced, if A decides it will no longer be "NameAware" the other classes won't broke.
这里 B 和 C 可以从 A 继承,这会在它们之间创建一个非常高的耦合,通过使用接口减少耦合,如果 A 决定它不再是“NameAware”,其他类不会中断。
Of course, if you want to reuse behavior this won't work.
当然,如果你想重用行为,这是行不通的。
回答by MF.OX
For those who Google for this error and arrive here: there might be another reason for receiving it. Eclipse gives this error when you have project setup - system configuration mismatch.
对于那些在谷歌上搜索这个错误并到达这里的人:可能有另一个接收它的原因。当您进行项目设置时,Eclipse 会出现此错误 - 系统配置不匹配。
For example, if you import Java 1.7 project to Eclipse and you do not have 1.7 correctly set up then you will get this error. Then you can either go to Project - Preference - Java - Compiler
and switch to 1.6 or earlier
; or go to Window - Preferences - Java - Installed JREs
and add/fix your JRE 1.7 installation.
例如,如果您将 Java 1.7 项目导入 Eclipse 并且您没有正确设置 1.7,那么您将收到此错误。然后你可以去Project - Preference - Java - Compiler
和switch to 1.6 or earlier
; 或转到Window - Preferences - Java - Installed JREs
并添加/修复您的 JRE 1.7 安装。
回答by BrainO2
You can solve this error by adding an argumentless constructor to the base class (as shown below).
您可以通过向基类添加无参数构造函数来解决此错误(如下所示)。
Cheers.
干杯。
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";
}
}
回答by user2407102
Another way is call super() with the required argument as a first statement in derived class constructor.
另一种方法是使用所需的参数调用 super() 作为派生类构造函数中的第一条语句。
public class Sup {
public Sup(String s) { ...}
}
public class Sub extends Sup {
public Sub() { super("hello"); .. }
}
回答by Sagar
Eclipse will give this error if you don't have call to super class constructor as a first statement in subclass constructor.
如果您没有调用超类构造函数作为子类构造函数中的第一条语句,Eclipse 将给出此错误。
回答by Thomas Johnson
I had this error and fixed it by removing a thrown exception from beside the method to a try/catch block
我遇到了这个错误并通过从方法旁边删除一个抛出的异常到 try/catch 块来修复它
For example: FROM:
例如: 发件人:
public static HashMap<String, String> getMap() throws SQLException
{
}
TO:
到:
public static Hashmap<String,String> getMap()
{
try{
}catch(SQLException)
{
}
}
回答by yogesh kumar
You could also get this error when JRE is not set. If so, try adding JRE System Libraryto your project.
如果未设置 JRE,您也可能会收到此错误。如果是这样,请尝试将JRE 系统库添加到您的项目中。
Under Eclipse IDE:
在 Eclipse IDE 下:
- open menu Project--> Properties, or right-click on your project in Package Explorerand choose Properties(Alt+Enter on Windows, Command+I on Mac)
- click on Java Build Paththen Librariestab
- choose Modulepathor Classpathand press Add Library...button
- select JRE System Librarythen click Next
- keep Workspace default JREselected (you can also take another option) and click Finish
- finally press Apply and Close.
- 打开菜单Project--> Properties,或在包资源管理器中右键单击您的项目并选择Properties(在 Windows 上为 Alt+Enter,在 Mac 上为 Command+I)
- 单击Java 构建路径,然后单击库选项卡
- 选择Modulepath或Classpath并按Add Library...按钮
- 选择JRE 系统库,然后单击下一步
- 保持Workspace 默认 JRE 处于选中状态(您也可以选择其他选项)并单击Finish
- 最后按Apply 和 Close。
回答by Serj.by
Sorry for necroposting but faced this problem just today. For everybody also facing with this problem - one of he possible reasons - you don't call super
at the first line of method. Second, third and other lines fire this error. Call of super should be very first call in your method. In this case everything is well.
很抱歉进行了 necroposting,但就在今天遇到了这个问题。对于每个也面临这个问题的人——他可能的原因之一——你不会super
在方法的第一行调用。第二、第三和其他行触发此错误。调用 super 应该是您方法中的第一个调用。在这种情况下,一切都很好。