【问题标题】:Why can't I create a parameterless subclass constructor when the baseclass has a constructor with a parameter?当基类有带参数的构造函数时,为什么我不能创建无参数的子类构造函数?
【发布时间】:2014-03-27 10:59:52
【问题描述】:

我知道以下方法不起作用,但你能帮我理解为什么吗?

class A {
    A(int x) { 
       System.out.println("apel constructor A"); 
    } 
}

class B extends A {
    B() { 
       System.out.println("apel constructor B"); 
    } 
}

public class C {
    public static void main(String args[]) { 
       B b = new B(); 
    } 
}

【问题讨论】:

  • +1 显然是明确的问题 - 如果只有其他问题也能在短短 9 分钟内获得如此多的关注。 ;)

标签: java inheritance constructor


【解决方案1】:

您的类A 使用显式参数构造函数,因此默认的无参数构造函数不会隐式出现。

为了让您的班级B 成功扩展A,您需要:

  • A 中声明的无参数显式构造函数
  • 或调用super(some int) 作为B 构造函数的第一行

考虑子类的构造函数隐式调用super()

【讨论】:

    【解决方案2】:

    每个构造函数(Object 除外)必须链接到另一个构造函数,这是它首先要做的事情。那是使用this(...)super(...)

    如果不指定任何内容,构造函数会隐式添加super() 以链接到超类中的无参数构造函数。迟早,您需要为继承层次结构的每一级都创建一个构造函数。这确保了对象的状态从各个角度来看都是有效的。

    在您的情况下,您在A 中没有无参数构造函数,因此B 无法编译。要解决此问题,您需要向A 添加无参数构造函数,或显式链接到B 中的参数化A 构造函数:

    public B() {
        super(0); // Or whatever value you want to provide
    }
    

    更多详情请见JLS section 8.8.7

    【讨论】:

      【解决方案3】:

      这不起作用,因为如果类 A 没有声明默认构造函数,您必须显式调用超类 A 的构造函数之一。

      【讨论】:

      • 所以要制作 B 的对象,我首先需要实际制作 A?
      • 不行,去做个继承教程
      • 您将构造函数调用的概念与对象创建混为一谈。调用构造函数不会创建对象,它会初始化现有对象。
      • 不,B 是一个 A,所以 B 的一部分是 A 也需要初始化 - 这是由构造函数完成的
      【解决方案4】:

      它无法编译,因为您没有为 A 定义默认构造函数,而 B 构造函数正在调用它。

      【讨论】:

        【解决方案5】:

        当你调用类'B'的构造函数时,你应该声明你希望父构造函数也被调用 例如

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

        这些构造函数中的任何一个都应该没问题

        【讨论】:

          【解决方案6】:

          你必须在子类Constructor中调用超类构造函数。

          B 是子类,它继承了超类 A 的行为。所以,当你创建 B 的实例时,B 的构造函数应该调用超类 Constructor。

          B() { 
             super(1); // or super()
             System.out.println("apel constructor B"); 
          }
          

          【讨论】:

          • 我不想让它工作,我想了解它为什么不能编译。
          • 它不能被编译,因为超类只有参数化的构造函数。默认情况下不调用参数化构造函数。因此子类默认不能创建超类对象。
          • @GeorgeIrimiciuc,答案在第一行
          【解决方案7】:

          每次你扩展一个类时,你扩展的类的构造函数都会被调用(超级构造函数)。如果您声明一个构造函数,它将覆盖隐式构造函数,如果该构造函数有参数,则您扩展的类将无法调用隐式构造函数,因此您必须显式调用构造函数。

          例子:

            B() { 
              super(0);//integer value
              System.out.println("apel constructor B"); }     
          }
          

          【讨论】:

            【解决方案8】:

            每当在Java中调用子类的构造函数时,它都会自动首先调用其超类的构造函数。总是先执行 Super 类的构造函数,然后执行 Sub 类的构造函数。 在这种情况下,超类构造函数在调用时需要一个整数参数,而代码未提供该参数。你可以试试这个:

            class B extends A
            {
              B()
              { 
                 super(5);
                 System.out.println("apel constructor B");
              }
            }
            

            【讨论】:

              【解决方案9】:

              我通过两种方式解决你的问题:-

              1. B 类扩展 A{ B(int x){超(x); System.out.println("你好第二个构造函数");} 公共静态 void main(String args[]){B b =new B(10);}} 2.

                B 类扩展 A{ B(){super(任何 int 值); System.out.println("你好第二个构造函数");} public static void main(String args[]){B b =new B(10);}}

              【讨论】:

                猜你喜欢
                • 2018-06-03
                • 2012-08-01
                • 2011-10-08
                • 2021-07-05
                • 1970-01-01
                • 2014-06-18
                • 1970-01-01
                • 2021-10-11
                • 2016-05-22
                相关资源
                最近更新 更多