代码之家  ›  专栏  ›  技术社区  ›  Joel

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

  •  85
  • Joel  · 技术社区  · 16 年前

    我有一个简单的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 ).

    这很好,但我不喜欢在子类中有冗余构造函数。它更容易打字,而且很难维护。如果我要更改 构造函数,我必须更改所有子类。

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

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

    我想做的事可能吗?

    10 回复  |  直到 14 年前
        1
  •  148
  •   matt b    16 年前

    出现此错误是因为没有构造函数的类具有 违约

    public ACSubClass() {
        super();
    }
    

    super();

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

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

        2
  •  51
  •   Dean Meehan    9 年前

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

    例如,如果您将Java1.7项目导入Eclipse,但没有正确设置1.7,则会出现此错误。那你可以去 Project - Preference - Java - Compiler switch to 1.6 or earlier ; 或者去 Window - Preferences - Java - Installed JREs

        3
  •  8
  •   OscarRyz    16 年前

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

    您必须向基类添加一个无参数构造函数,就这样!

    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构造函数。

    当defualt no 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");
    

    如果要更改基类构造函数的方法签名,则必须更改所有子类。

    这就是为什么继承是创建高耦合的工件,这在OO系统中是不受欢迎的。应该避免这种情况,或者用构图代替。

    如果您真的需要它们作为子类,请思考。这就是为什么您经常看到使用insted的接口:

     public interface NameAware {
         public String getName();
     }
    
    
    
     class A implements NameAware ...
     class B implements NameAware ...
     class C ... etc. 
    

    在这里,B和C可以从A继承,而A会在它们之间创建一个非常高的耦合,通过使用接口,耦合会减少,如果A决定不再是“名称感知”的,其他类就不会中断。

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

        4
  •  4
  •   Emilio M. yogesh kumar    8 年前

    如果未设置JRE,也可能会出现此错误。如果是,请尝试添加 JRE系统库 你的项目。

    1. 打开菜单 计划 --&燃气轮机; 性质 包资源管理器 选择 性质 (Windows上Alt+Enter,Mac上Command+I)
    2. 点击 Java构建路径 然后 图书馆 标签
    3. 类路径 添加库。。。
    4. 选择 JRE系统库 下一个
    5. 工作区默认JRE 选中(您也可以选择其他选项)并单击 完成
    6. 最后按 .
        5
  •  2
  •   user2407102    12 年前

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

    public class Sup {
        public Sup(String s) { ...}
    }
    
    public class Sub extends Sup {
        public Sub() { super("hello"); .. }
    }
    
        6
  •  1
  •   Uttam Pawar    5 年前

    我已将上述问题解决如下:

    1. 点击项目。
    2. 单击属性>Java构建路径>图书馆>JRE系统库>编辑
    3. 选择默认系统JRE并完成
    4. 应用并关闭。
        7
  •  0
  •   Sagar    11 年前

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

        8
  •  0
  •   Serj.by    8 年前

    super 在方法的第一行。第二行、第三行和其他行触发此错误。super的调用应该是方法中的第一个调用。在这种情况下,一切都很好。

        9
  •  0
  •   Fabala Dibbasey    5 年前

    简短答复: 在base/parent/super类中添加一个没有参数的构造函数。i、 e例如,

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

    //在父类中,您可以根据需要使用任何其他构造函数。

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

    //那我们继承吧

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

    对于super(),调用一个超类无参数构造函数;对于super(参数列表),调用一个具有匹配参数列表的超类构造函数。

        10
  •  0
  •   Mukta    5 年前

    下面是一个简单的例子

    public class A {
        public A(int i){
           //
        }
    
     }
    
    class B extends A {
        public B(int i){
          super(i);
        }
      }
    
        11
  •  -1
  •   BrainO2    12 年前

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

    干杯。

     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";
        }
    }
    
        12
  •  -1
  •   depperm    9 年前

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

    例如: 发件人:

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

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