44

我是java编程语言的初学者,最近研究了java中不能继承构造函数,谁能解释一下为什么

我已经阅读了 C++ 的这个链接

4

12 回答 12

45

简单来说,构造函数不能被继承,因为在子类中它有不同的名称(子类的名称)。

class A {
   A();
}

class B extends A{
   B();
}

你只能做:

B b = new B();  // and not new A()

相反,方法以“相同的名称”继承并且可以使用。

至于原因:继承构造函数没有多大意义,因为A类的构造函数就是创建A类的对象,B类的构造函数就是创建B类的对象。

不过,您仍然可以在 B 的实现中使用来自 A 的构造函数:

class B extends A{
   B() { super(); }
}
于 2013-08-09T13:32:31.177 回答
20

您所说的是Java语言级别。如果构造函数是继承的,那将不可能将类设为私有。正如我们所知,方法可见性不能降级。Object类有一个无参数构造函数,每个类都 extends Object,所以在构造函数继承的情况下,每个类都有一个无参数构造函数。这违反了OO原则。

字节码级别的情况有所不同。创建对象时,会调用两个运算符:

  1. new - 为对象分配内存
  2. invokespecial - 在新分配的内存块上调用构造函数

我们可以修改字节码,以便为子类分配内存,并从父类调用构造函数。在这种情况下,我们可以说构造函数是继承的。请注意,如果我们不关闭字节码验证,JVM 将在加载类时抛出异常。我们可以通过添加-noverify参数来做到这一点。

结论:

  1. 由于 OO 原则,构造函数不会在语言级别上继承
  2. 构造函数在字节码级别继承
于 2013-08-12T07:04:16.263 回答
13

继承文档中提到的原因

子类从其超类继承所有成员(字段、方法和嵌套类)。构造函数不是成员,所以子类不能继承,但是子类可以调用超类的构造函数。

您可以参考为您的类提供构造函数的文档

于 2013-08-09T13:28:44.703 回答
3

构造函数不是类的成员,只有成员被继承。您不能继承构造函数。也就是说,您不能使用其中一个超类的构造函数来创建子类的实例。

于 2013-08-09T13:30:00.553 回答
3
  • 只能使用 调用构造函数new。它不能被称为方法。
  • 构造函数名称与类名称相同。

所以继承实际上是不可能的。然而,在一个构造中,可能会调用其他构造函数。

  • 在同一个类中使用this(...);
  • 使用的扩展类super(...)

例子

class A {
    A() { }          // Constructor
    A(int a) { }     // Constructor
    A(boolean c) { } // Constructor
}
class B extends A {
    B() {
        this(3, 7);
    }
    B(int a) {
        super();
    }
    B(String b) {
        super(7);
    }
    B(int a, int c) { // Calls super() implicitly
    }
}
A a = new B(8):

不幸的是,不可能将 A 的构造函数用于布尔值:

B b = new B(true): // ERROR

语言设计可以实现这样的东西:

如果尚未定义此类构造函数,则为基类中的每个公共构造函数生成具有相同签名的构造函数。super使用相同的参数调用。this()如果有默认构造函数则调用。

这似乎有点臃肿的代码。并且不仅仅是虚拟方法表中的指针,方法继承/覆盖通过该指针起作用。

于 2013-08-09T14:09:04.827 回答
2

我观察到的简单答案,您不能直接在子类中调用或使用父类的构造函数,但可以在子类中直接使用父类的方法。

如果您当时在子类中有与父类同名的方法,则只需使用“super”关键字来调用父类方法解决调用歧义。

在子类中“调用”父类构造函数,您总是需要“super”关键字。所以父类构造函数像子类中的父类方法一样“不直接可用”,所以我们可以说构造函数不能被继承。

于 2015-05-22T15:01:58.703 回答
2
  1. 如果构造函数是在子类中继承的,那么子类将包含一个父类构造函数,这违反了构造函数应该与类名同名的约束。
  2. 但是,可以使用 super() 从子类构造函数调用父类构造函数。

演示该概念的示例代码。

class Base{
   public void Base()
   {
       System.out.println("Inside Base class constructor");
   }
}
class Derived{
   public void Derived()
   {
       super();
       System.out.println("Inside Derived class constructor");
   }
class mainClass{
   public static void main(String args[])
   {
       Derived obj = new Derived();
   }


Output:
Inside Base class constructor
Inside Derived class constructor
于 2020-07-06T17:29:14.670 回答
1

你不能继承构造函数,但你可以继承构造函数中的初始化值,比如

class test1 {
    int a,b;
    test1(){
        a = 100;
        b = 20;
    }
}

class test2 extends test1 {
    test2(){
        // do something
    }
}

class test {
    public static void main(String[] args) {
        test2 t = new test2();
        int a = t.a;
        int b = t.b;
        System.out.println(a+b);
    }
}
于 2017-10-08T08:51:26.027 回答
1

如果某个特性有任何理由以概念方式出现,则通常可以规避句法限制。有了这个,我相信,不支持构造函数继承的真正原因不是由于语法限制,而是由于语义。

从概念上讲,继承提供了一种获取(或继承)行为的机制,并且很可能无需编写任何代码,因为它的目的是提供代码重用。对于子类,没有必要继承其父类的初始化行为。毕竟,当外部调用者可以在不知道谁(在父链中)实际实现它的情况下使用它时,继承的行为会找到它的最佳用途。如您所见,调用者几乎不知道如何通过其子类初始化父类,没有明显的理由支持(父类的)构造函数的继承。

于 2016-09-16T15:44:48.430 回答
1

只有字段、方法和嵌套类是任何类的成员,而不是构造函数。子类从其超类继承所有成员,例如(字段、方法和嵌套类)。构造函数不是成员,所以子类不能继承,但是子类可以调用超类的构造函数。

于 2016-06-28T04:42:00.277 回答
1

不,构造函数不会被继承到子类,即使它是一个非静态成员,它也不会被继承到子类,因为构造函数不会被加载到对象内部,它用于创建对象。构造函数就像一个非静态初始化器

于 2016-01-16T06:58:53.623 回答
1

不,正如米哈伊尔所说;构造函数不被继承。

您不能将构造函数继承superclass到您的subclass. 但是,当在 java 中使用“new”运算符实例化一个对象时,该对象会从它的子类继承所有构造函数,superclass(parent)甚至包括抽象类中的构造函数(因为它们也是超类)。

于 2019-05-27T10:47:49.557 回答