【问题标题】:constructor of subclass in JavaJava子类的构造函数
【发布时间】:2012-03-24 02:08:00
【问题描述】:

在编译这个程序时,我得到了错误-

 class Person {
    Person(int a) { }
 }
 class Employee extends Person {
    Employee(int b) { }
 }
 public class A1{
    public static void main(String[] args){ }
 }

错误 - 找不到构造函数 Person()。 为什么需要定义 Person()?

【问题讨论】:

  • 使用诸如 Eclipse 之类的 IDE 会立即为您提供更正的提示和快捷方式。

标签: java constructor superclass


【解决方案1】:

创建Employee 时,您同时创建了Person。为了确保Person 构造正确,编译器在Employee 构造函数中添加了对super() 的隐式调用:

 class Employee extends Person {
     Employee(int id) {
         super();          // implicitly added by the compiler.
     }
 }

由于Person 没有无参数构造函数,因此失败。

你可以解决它

  • 添加对 super 的显式调用,如下所示:

     class Employee extends Person {
         Employee(int id) {
             super(id);
         }
     }
    
  • 或通过向Person 添加无参数构造函数:

    class Person {
        Person() {
        }
    
        Person(int a) {
        }
    }
    

通常编译器也会隐式添加无参数构造函数。然而,正如 Binyamin Sharet 在 cmets 中指出的那样,只有在根本没有指定构造函数的情况下才会出现这种情况。在您的情况下,您已经指定了 Person 构造函数,因此没有创建隐式构造函数。

【讨论】:

  • +1 值得一提的是默认有一个空的构造函数,但是当你添加一个构造函数时,这个空的构造函数就不再使用了。
【解决方案2】:

Employee 的构造函数不知道如何构造超类Person。如果没有您明确告诉它,它将默认尝试不存在的超类的无参数构造函数。因此出现错误。

解决方法是:

class Employee extends person {
    public Employee(int id) {
        super(id);
    }
}

【讨论】:

    【解决方案3】:

    Java 实际上将此代码视为:

    class Person {
      Person(int nm) { }
     }
     class Employee extends Person {
        Employee(int id) {
            super();
        }
     }
     public class EmployeeTest1 {
        public static void main(String[] args){ }
     }
    

    由于没有 Person() 构造函数,因此失败。而是尝试:

    class Person {
      Person(int nm) { }
     }
     class Employee extends Person {
        Employee(int id) {
            super(id);
        }
     }
     public class EmployeeTest1 {
        public static void main(String[] args){ }
     }
    

    【讨论】:

      【解决方案4】:

      Java 为您提供了一个不带参数的默认构造函数。构造函数也没有主体,所以它是这样的:public Person() {}。在您定义自己的构造函数的那一刻,您的构造函数将替换默认构造函数,因此在您的情况下,Person(int nm){} 将替换 Person() { }。您的调用试图隐式调用 Person() { } 并且由于此构造函数不再存在,因此代码失败。查看this之前的SO问题以获取更多信息。

      【讨论】:

        【解决方案5】:

        以上答案是正确的,补充一点:您可以直接调用 super(int n) 以避免在此处隐式添加 super():

        class Employee extends Person {
            Employee(int id) { super(int id);}
        }
        
        1. 如果您不编写构造函数,编译器会隐式将默认值(不带参数)添加到您的类中。
        2. 如果您编写任何构造函数 - 编译器将不会添加默认构造函数。

        PS:对不起,我的写作。英语不是我的母语。

        【讨论】:

          【解决方案6】:

          这不是 100% 与您的问题有关。但这也与java构造函数有关。假设您的 Person 类没有默认构造函数,并且构造函数参数不是原始数据类型。它们是对象。

          但是如果你想创建一个带有默认构造函数的子类,这里是解决方案。 请记住,您不能更改超类。

          我创建了另一个名为contact的类。

          class Contact{
              private String name;
              private int number;
          
              public Contact(String name, int number) {
                  this.name = name;
                  this.number = number;
              }
          }
          

          然后这里是代码。

          //Super Class   -  "Can't change the code"
          class Person {
              Person(Contact contact) { }
          }
          
          //Sub Class
          class Employee extends Person {
              private static Contact c;
          
              static {
                  c = new Contact("Anna",10);
              }
          
              Employee() {
                  super(c);
              }
          }
          

          您必须使用 Contact 类的静态变量来保存一个对象实例,以便传递给超类构造函数。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-02-28
            • 2021-03-12
            • 1970-01-01
            • 1970-01-01
            • 2018-06-13
            • 2014-11-06
            • 1970-01-01
            相关资源
            最近更新 更多