【问题标题】:Undefined constructor (java)未定义的构造函数(java)
【发布时间】:2015-02-12 23:24:30
【问题描述】:

所以我有一个名为 User 的 java 类,其中包含这样的构造函数:

public class User extends Visitor {
    public User(String UName, String Ufname){
        setName(UName);
        setFname(Ufname);
    }
}

然后他的问题出现在我的另一个名为 Admin 的课程中​​:

public class Admin extends User {  //error "Implicit super constructor User() is undefined for default constructor. Must define an explicit constructor"

//public Admin() { } //tried to add empty constructor but error stays there

    //}


    public void manage_items() {            

        throw new UnsupportedOperationException();
    }

    public void manage_users() {   

        throw new UnsupportedOperationException();
    }
}

我收到错误 Implicit super constructor User() is undefined for default constructor. Must define an explicit constructor at the place marked in the code. 我不知道如何解决这个问题,而且我真的是 java 新手。

【问题讨论】:

    标签: java inheritance methods constructor


    【解决方案1】:

    如果您不向类添加构造函数,则会自动为您添加一个构造函数。对于 Admin 类,它将如下所示:

    public Admin() { 
        super();
    }
    

    调用 super() 是调用父 User 类中的如下构造函数:

    public User() {
        super();
    }
    

    由于此构造函数不存在,您会收到错误消息。

    有关默认构造函数的更多信息,请参见此处: http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

    您不必为您的类提供任何构造函数,但这样做时必须小心。编译器会自动为任何没有构造函数的类提供无参数的默认构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会报错,因此您必须验证它是否存在。如果你的类没有显式的超类,那么它有一个 Object 的隐式超类,它确实有一个无参数的构造函数。*

    【讨论】:

    • 调用超类Admin时,必须传递有效参数,而不是把括号留空。
    • 请修正调用超类构造函数时的参数,你的答案是错误的。
    • 但我的用户确实有一个构造函数我不能只留下删除参数 public User() 有需要留在那里的参数
    • @Phil_oneil 我已经回答了您收到错误消息的原因。有关可能的解决方案,请参阅 Elliott Frisch 的答案。
    【解决方案2】:

    您必须在扩展Visitor 类的构造函数的第一个类似处调用Visitor 的构造函数,使用super()

    public User(String UName,String Ufname){
        super();
        setName(UName);
        setFname(Ufname);
    }
    

    如果你想让 Admin 也有一个自定义构造函数,你必须调用:

    super(uname, ufname) // String, String - pass the params of the superclass cunstructor
    

    所以:

    public Admin() {
        super(someString, someString);
    }
    

    【讨论】:

    • 错误仍然存​​在。访问者没有构造函数。它不需要一个,管理员也不需要一个
    • @Phil_oneil 你错了,正如你看到的,User确实有一个构造函数,所以需要在任何扩展User的类中调用它
    • 就像我说的那样,我对 java 很陌生,我也添加了你告诉我的内容,但错误仍然存​​在。我添加了访问者类以备不时之需
    • @Phil_oneil 究竟是什么错误?你能提供吗?
    • 您的信息有误。从来不需要调用super() 并且调用“总是很好”是代码风格的问题,仅此而已。没有必要手动调用super(),因为调用父构造函数总是子构造函数要做的第一件事,应该省略明显的代码以避免代码混乱。不,如果父类只有一个重载的构造函数(称为重载而不是覆盖),则不需要手动调用super(),因为这个调用会失败。
    【解决方案3】:

    您的Admin 类扩展了User,而User 没有默认构造函数。您需要使用带有两个String(s) 和super 的构造函数。类似的,

    public Admin() {
      super("a", "b"); // <-- first line.
    }
    

    或者,您可以将无参数构造函数添加到 User

    public User() {
    }
    

    然后你当前的Admin 将编译。

    【讨论】:

      【解决方案4】:

      你需要知道两件事:

      1. 在每个构造函数的开始,都会调用超类的构造函数。它由

        表示
        • super() - 调用超类的无参数构造函数
        • super(your,arguments) - 调用与传递给 super(..) 的类型相同的构造函数处理参数。

        如果我们想使用无参数构造函数,我们实际上不需要编写super(),因为编译器会在二进制文件中添加表示对super() 的调用的代码,但是如果我们想用参数调用super,因为

        • 它无法决定要使用哪个带有超类参数的构造函数,
        • 以及应该在那里传递什么值(参数),

        所以在这种情况下,您需要自己在构造函数的开头显式编写super(your,arguments)

      2. 如果你不向你的类添加任何构造函数,编译器将添加默认构造函数,它没有参数,它唯一的指令将调用超类super()的无参数构造函数。换句话说,像

        这样的类的代码
        class Base{}
        class Derived extends Base{}
        

        和这段代码一样

        class Base extends Object{
            Base(){
                super();//will try to call Object() constructor
            }
        }
        class Derived extends Base{
            Derived(){
                super();//will try to call Base() constructor
            }
        }
        

      现在因为在User 类中只有一个构造函数User(String UName,String Ufname) 当你尝试编译时

      public class Admin extends User {  
      
          public void manage_items() {            
              //...
          }
      
          public void manage_users() {   
              //...
          }
      }
      

      编译器将其视为

      public class Admin extends User {  
      
          public Admin(){
              super();
          }
      
          public void manage_items() {            
              //...
          }
      
          public void manage_users() {   
              //...
          }
      }
      

      现在你看到问题出在

          public Admin(){
              super();
          }
      

      因为super() 将尝试调用无参数User() 构造函数,但没有这样的构造函数,因为User 类中只有现有构造函数是User(String,String)

      因此,要完成这项工作,您需要添加Admin 构造函数并在其开始调用super(someString, someString)

      所以考虑添加到您的 Admin 类构造函数中,如下所示:

       public Admin(String aName,String Afname){
           super(aName, Afname);
           //here you can place rest of your constructors code
       }
      

      【讨论】:

        猜你喜欢
        • 2011-04-11
        • 1970-01-01
        • 2022-01-02
        • 2011-04-13
        • 2018-01-04
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        相关资源
        最近更新 更多