为什么构造函数不能在java中继承?

时间:2013-08-09 13:27:46

标签: java inheritance constructor

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

我已经阅读了C ++的this link

12 个答案:

答案 0 :(得分:35)

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

class A {
   A();
}

class B extends A{
   B();
}

你只能做:

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

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

原因如下: 继承构造函数没有多大意义,因为类A的构造函数意味着创建类型A的对象,而类B的构造函数意味着创建类B的对象。

你仍然可以在A的B实现中使用构造函数:

class B extends A{
   B() { super(); }
}

答案 1 :(得分:15)

您所谈论的是Java语言级别。如果构造函数是继承的,那么就不可能使类成为私有的。我们知道方法可见性不能降级。 Object类有一个无参数构造函数,每个类都扩展Object,因此在构造函数继承的情况下,每个类都有一个无参数构造函数。这打破了OO原则。

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

  1. new - 为对象分配内存
  2. invokespecial - 在新分配的内存块上调用构造函数
  3. 我们可以修改字节码,以便为Child类分配内存,并从Parent类调用构造函数。在这种情况下,我们可以说构造函数是继承的。如果我们不关闭字节码验证,JVM将在加载类时抛出异常。我们可以通过添加-noverify参数来完成此任务。

    <强>结论:

    1. 由于OO原则,构造函数不会在语言级别上继承
    2. 构造函数在字节码级别上继承

答案 2 :(得分:12)

Reason mentioned in docs of Inheritance

  

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

您可以参考Providing Constructors for Your Classes

的文档

答案 3 :(得分: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()

这似乎有点膨胀代码。并不仅仅是虚方法表中的指针,继承/覆盖的方法也适用于该方法。

答案 4 :(得分:2)

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

答案 5 :(得分:2)

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

如果您在子类中的方法与父类中的方法相同,那么只需要使用“super”关键字来调用父类方法解决调用歧义。

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

答案 6 :(得分:2)

  1. 如果构造函数是在子类中继承的,则子类将包含一个父类构造函数,这与构造函数应具有与类名相同的名称的约束相反。
  2. 但是,可以使用super()从子类构造函数中调用父类构造函数。

用于演示该概念的示例代码。

CalcJacobianCenterOfMassTranslationalVelocity

答案 7 :(得分:1)

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

答案 8 :(得分:1)

只有字段,方法和嵌套类是任何类的元素,而不是构造函数。子类从其超类继承所有成员,如(字段,方法和嵌套类)。构造函数不是成员,因此它们不是由子类继承的,但是可以从子类调用超类的构造函数。

答案 9 :(得分:1)

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

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

答案 10 :(得分: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);
    }
}

答案 11 :(得分:1)

没有米哈伊尔所说的;构造函数不被继承。您不能将构造函数从超类继承到子类中。但是,当用Java中的“ new”运算符实例化一个对象时,该对象会将其子类的所有构造函数继承到其父类(父类),甚至包括抽象类中的那些构造子(因为它们也是父类)。