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

发布于 2024-07-29 06:59:59 字数 832 浏览 4 评论 0原文

我有一些简单的 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() 方法方式(模板方法模式)。

这很好用,但我不喜欢在子类中使用多余的构造函数。 打字比较多,维护也比较困难。 如果我要更改 BaseClass 构造函数的方法签名,我就必须更改所有子类。

当我从子类中删除构造函数时,出现以下编译时错误:

默认构造函数的隐式超级构造函数 BaseClass() 未定义。 必须定义一个显式构造函数

我想要做的事情可能吗?

I have a some simple Java code that looks similar to this in its structure:

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).

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.

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

Is what I am trying to do possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

许久 2024-08-05 06:59:59

您会收到此错误,因为没有构造函数的类具有 default 构造函数,该构造函数是无参数的,相当于以下代码:

public ACSubClass() {
    super();
}

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

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

解决这个问题的最简单方法是基类不声明构造函数(因此具有默认的无参数构造函数)或具有声明的无参数构造函数(单独或与任何其他构造函数一起)。 但通常这种方法无法应用 - 因为您需要将任何参数传递到构造函数中来构造该类的合法实例。

You get this error because a class which has no constructor has a default constructor, 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.

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.

堇年纸鸢 2024-08-05 06:59:59

对于那些通过 Google 搜索此错误并到达此处的人:可能还有其他原因收到该错误。 当您的项目设置 - 系统配置不匹配时,Eclipse 会出现此错误。

例如,如果您将 Java 1.7 项目导入 Eclipse,并且没有正确设置 1.7,那么您将收到此错误。 然后您可以转到项目 - 首选项 - Java - 编译器切换到1.6或更早版本; 或者转至 Window - Preferences - Java - Installed JRE 并添加/修复 JRE 1.7 安装。

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.

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.

︶ ̄淡然 2024-08-05 06:59:59

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

您必须向基类添加一个无参数构造函数,仅此而已!

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)时,编译器会为您添加默认的无参数构造函数。

当默认没有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 构造函数的方法签名,我就必须更改所有子类。

这就是为什么继承是创建高耦合的工件,这在 OO 系统中是不受欢迎的。 应该避免它,也许可以用组合来代替。

想想你是否真的需要它们作为子类。 这就是为什么您经常看到使用插入的接口:

 public interface NameAware {
     public String getName();
 }



 class A implements NameAware ...
 class B implements NameAware ...
 class C ... etc. 

这里 B 和 C 可能继承自 A,这会在它们之间创建非常高的耦合,通过使用接口,耦合会降低,如果 A 决定它将不再是“NameAware”其他类不会中断。

当然,如果你想重用行为,这是行不通的。

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.

When the defualt no arg calls to super(); and since you don't have it in the super class you get that error message.

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.

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.

Think if you really really need them as subclass. That's why you see very often interfaces used 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.

Of course, if you want to reuse behavior this won't work.

葬シ愛 2024-08-05 06:59:59

当未设置 JRE 时,您也可能会收到此错误。 如果是这样,请尝试将JRE系统库添加到您的项目中。

在 Eclipse IDE 下:

  1. 打开菜单 Project --> 属性,或在Package Explorer中右键单击您的项目,然后选择属性(Windows 上为 Alt+Enter,Mac 上为 Command+I)
  2. 单击在Java构建路径上,然后在选项卡上
  3. 选择模块路径类路径,然后按添加库...< /em> 按钮
  4. 选择JRE 系统库,然后单击下一步
  5. 保持选中工作区默认 JRE(您也可以采用其他选项)并单击完成
  6. 最后按应用并关闭

You could also get this error when JRE is not set. If so, try adding JRE System Library to your project.

Under Eclipse IDE:

  1. open menu Project --> Properties, or right-click on your project in Package Explorer and choose Properties (Alt+Enter on Windows, Command+I on Mac)
  2. click on Java Build Path then Libraries tab
  3. choose Modulepath or Classpath and press Add Library... button
  4. select JRE System Library then click Next
  5. keep Workspace default JRE selected (you can also take another option) and click Finish
  6. finally press Apply and Close.
街道布景 2024-08-05 06:59:59

另一种方法是调用 super() 并将所需参数作为派生类构造函数中的第一个语句。

public class Sup {
    public Sup(String s) { ...}
}

public class Sub extends Sup {
    public Sub() { super("hello"); .. }
}

Another way is call super() with the required argument as a first statement in derived class constructor.

public class Sup {
    public Sup(String s) { ...}
}

public class Sub extends Sup {
    public Sub() { super("hello"); .. }
}
淡看悲欢离合 2024-08-05 06:59:59

我已经解决了上述问题,如下所示:

  1. 单击“项目”。
  2. 单击属性> Java 构建路径 > 图书馆> JRE系统库> 编辑
  3. 选择默认系统 JRE 并完成
  4. 应用并关闭。

I have resolved above problem as follows:

  1. Click on Project.
  2. click on properties > Java Build Path > Library > JRE System Library > Edit
  3. Select default system JRE And Finish
  4. Apply and close.
狂之美人 2024-08-05 06:59:59

这是一个简单的例子

public class A {
    public A(int i){
       //
    }

 }

class B extends A {
    public B(int i){
      super(i);
    }
  }

Here is simple example

public class A {
    public A(int i){
       //
    }

 }

class B extends A {
    public B(int i){
      super(i);
    }
  }
蔚蓝源自深海 2024-08-05 06:59:59

如果您没有调用超类构造函数作为子类构造函数中的第一个语句,Eclipse 将给出此错误。

Eclipse will give this error if you don't have call to super class constructor as a first statement in subclass constructor.

枉心 2024-08-05 06:59:59

抱歉,死了,但今天才遇到这个问题。 对于每个也面临这个问题的人来说(可能的原因之一),您不会在方法的第一行调用 super 。 第二、第三行和其他行会引发此错误。 super 的调用应该是您的方法中的第一个调用。 在这种情况下一切都很好。

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.

冷夜 2024-08-05 06:59:59

简短回答:
在基类/父类/超类中添加一个不带参数的构造函数。 例如,

        class Parent{
    
    String name;
    int age;
    String occupation;
            //empty constructor
            public Parent(){
            
        }
    
    public Parent(String name, int age, String employment){
    this.name = name;
    this.age = age;
    this.occupation = employment;
    }
}

// 您可以根据需要添加任何其他构造函数,也称为父类中的构造函数重载。

如果超类没有无参构造函数,那么您将收到编译时错误。 Object确实有这样的构造函数,所以如果Object是唯一的超类那么就没有问题。

// 然后让我们继承

    class Child extends Parent{
              Child(String name, int age){
this.name = name;
this.age = age;
    }
    
    }

使用 super() ,调用超类无参数构造函数,使用 super(parameter list) ,调用具有匹配参数列表的超类构造函数。

Short answer:
Add a constructor with no argument in base/parent/super class. i.e for example,

        class Parent{
    
    String name;
    int age;
    String occupation;
            //empty constructor
            public Parent(){
            
        }
    
    public Parent(String name, int age, String employment){
    this.name = name;
    this.age = age;
    this.occupation = employment;
    }
}

// You can have any additional constructors as you wish aka constructor overloading here in parent class.

If a super class does not have the no-argument constructor then you will get the compile-time error. Object does have such the constructor, so if Object is a only super class then there is no problem.

// then let's inherit

    class Child extends Parent{
              Child(String name, int age){
this.name = name;
this.age = age;
    }
    
    }

With super(), a super class no-argument constructor is called and with super(parameter list), a super class constructor with the matching parameter list is called.

套路撩心 2024-08-05 06:59:59

您可以通过向基类添加无参数构造函数来解决此错误(如下所示)。

干杯。

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

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";
    }
}
注定孤独终老 2024-08-05 06:59:59

我遇到了这个错误,并通过从方法旁边删除抛出的异常到 try/catch 块来修复它,

例如:

public static HashMap<String, String> getMap() throws SQLException
{

}

到:

public static Hashmap<String,String> getMap()
{
  try{

  }catch(SQLException)
  { 
  }
}

I had this error and fixed it by removing a thrown exception from beside the method to a try/catch block

For example:
FROM:

public static HashMap<String, String> getMap() throws SQLException
{

}

TO:

public static Hashmap<String,String> getMap()
{
  try{

  }catch(SQLException)
  { 
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文