Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Can';t直接调用超类型构造函数-为什么不?_Java_Constructor - Fatal编程技术网

Java Can';t直接调用超类型构造函数-为什么不?

Java Can';t直接调用超类型构造函数-为什么不?,java,constructor,Java,Constructor,我有以下Java示例类: public class A { } public class Super { protected Super() { } public Super(A a) { } } public class Sub extends Super { } public class Consumer { public Consumer() { Sub sub = new Sub(new A()); //compiler error

我有以下Java示例类:

public class A { }

public class Super {
    protected Super() { }
    public Super(A a) { }
}

public class Sub extends Super { }

public class Consumer {
    public Consumer() {
        Sub sub = new Sub(new A()); //compiler error
    }
}
编译器错误声明参数不能应用于Sub中的默认构造函数,这是完全可以理解的

我好奇的是这个决定背后的理由。Java在
Sub
中生成默认的空构造函数;在这种情况下,为什么不能称之为幕后呢?这主要是一种理智的手牵手,还是有技术上的原因

编辑

我知道这是一种语言限制。我很好奇为什么这是一种语言限制

编辑2

看起来,就像通常的情况一样,我离实际使用的代码太近了,看不到全局。我在下面的答案中贴了一个反例,说明了为什么这是一件坏事

public class Sub extends Super { }
没有构造函数子(A),它只有默认构造函数子()


构造函数不是继承的。

您已经覆盖了默认的公共构造函数,因此没有任何可调用的内容

所以Sub类等价于

public class Sub extends Super
{
    protected Sub(){}
    public Sub(A a) { }
}
那是因为

  • Sane行为-按照程序员指定的行为,它还遵循OOP语言中的继承概念
  • 遵循C++遗产
      基类需要调用超级构造函数,以确保正确实例化对象。例如,考虑:

      class Super {
         final String field1;
      
         public Super(String field1) {
            this.field1 = field1;
         }
         ...
      }
      
      
      class Base extends Super {
         final String field2;
      
         public Base(String field2) {
            this.field2 = field2;
         }
         ...
      }
      
      Base
      的构造函数是否覆盖了
      Super
      构造函数?如果是这样,那么field1就不再保证被初始化,这使得继承的方法表现出意外的行为


      当您向子类添加非默认构造函数时,继承的构造函数就会停止工作。我认为,如果将它添加到语言中,这将是一个令人困惑且几乎没有用处的功能,尽管从技术上讲,我看不出为什么它不可能实现。

      我认为这是一个易读性和不假设意图的问题。你说

      Java生成默认的空构造函数;在这种情况下,为什么不能称之为幕后呢

      然而,对我来说,Java隐式调用
      Super(A)
      构造函数“幕后”比调用
      Super()
      构造函数更有意义,忽略
      A

      就在这里。对于这种情况下应该(或可能)发生什么,我们已经有了两种截然不同的假设

      Java语言的核心原则之一是透明性。程序员应该尽可能通过查看代码来了解将要发生的事情,有时会以牺牲语法层面的便利性或魔力为代价


      与此类似的一个原则是不假设意图:在程序员的意图看起来模棱两可的情况下,Java语言有时会倾向于编译错误,而不是通过某种(任意或其他)选择算法自动选择默认值;我同意其他几个答案,这可能在语义上令人困惑

      考虑以下示例:

      public class A { }
      
      public abstract class Super {
          protected Super() {
              // perform time consuming, destructive, or
              // otherwise one-time operations
          }
      
          public Super(A a) {
              this();
              // perform A-related construction operations
          }
      }
      
      public class Sub extends Super { }
      
      public class Consumer {
          public Consumer() {
              Sub sub = new Sub(new A());
          }
      }
      
      当构造
      Sub
      时,在这种情况下将调用
      Sub
      上的默认构造函数,它将链接到
      Super
      上的默认构造函数(因为这是语言定义的魔力)。然后,对
      Super(A)
      的调用将调用设计为在构造时运行一次的逻辑。这显然不是开发者的意图


      即使没有
      Super(A)
      构造函数中的
      this()
      调用,也无法确定开发人员的意图;由于某些原因,构造器可能相互排斥。

      这是好的观点,但您似乎误解了我的说法。我会更新它,让它更清楚。这可能不会改变你的论点…这是Jon Skeet的观点我对你的编辑感到困惑。你想知道为什么当你用一个参数调用一个构造函数时,一个没有参数的默认构造函数不能在它的位置被调用?显然,程序员并没有试图调用完全忽略其参数的构造函数,否则他就不会指定参数!“创建默认无参数构造函数”和“为父级中的每个构造函数创建阴影构造函数”类型之间存在差异。并没有太大的魔力,因为Java并没有做到这一点。除了Java冗长语法的另一个方面(让人恼火的是),没有关于“手持”的内容;-)(构造函数从来都不是虚拟的/重写的。)我想知道为什么不能为
      Sub
      调用默认构造函数,并将参数传递给
      Super
      。当我这样想的时候,我认为这实际上是一种情况,如果我不必一直指定默认构造函数来将这些类与GSON一起使用,我就不会遇到这种情况。但是,考虑到这一点,我想我已经回答了自己的问题——当Java在
      Sub
      中构建默认构造函数时,它会自动在
      Super
      中包含对默认构造函数的调用。因此,如果调用
      Super(A)
      构造将发生两次。@JonathanSpooner-感谢链接到Jon的答案,但这不是完全相同的问题。这个反例的问题是它不涉及默认的构造函数。您认为此代码有问题是正确的;它甚至不会编译。但是,我的问题是关于默认构造函数的。您的示例之所以有效,是因为Sub没有构造函数,如果构造函数仅在这些情况下继承,这将是一个令人困惑的特性。我的示例之所以有问题,只是因为
      Sub
      没有构造函数。我同意你的说法,这会让人困惑,但这个问题是想找出为什么会让人困惑。@mikek3332002:我想我们只能调用超类构造函数