Java 中的继承和构造函数

Inheritance and constructors in Java

在下面的例子中:

class A {  
    private int a;
    private int b;
    private int c;

    public A(int a, int b , int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
}

class B extends A {
    public B() {
         super(1,2,3);         
    }
  1. class B中的语句super(1,2,3)是否创建了与classA中的私有字段相同的私有字段?还是因为B不能继承A的私有字段,所以使用这个语句是不合法的?
  2. 并且我们假设我们没有在 class B 中使用超级构造函数那么通常计算机将调用 class A 的默认构造函数。我们知道私有字段不是在 Java 中继承 那么默认构造函数将在此状态下初始化什么?

你不能这样调用 super():

 class B extends A {
      super(1,2,3);
   }

super() OR this() 应该是构造函数中的第一条语句。在继续之前先纠正你的这个基本错误。 super() 默认使用,即使您没有明确使用它。

class B extends A {
    B (){
       super(1,2,3);
    }
}

这是正确的方法。请在发帖前先阅读 Constructors 和 Java 语言基础知识。

编辑

我没有注意到有人编辑你的问题在构造函数中添加 super(1,2,3),现在回答你的问题如下:

Does the statement super(1,2,3) in the class B create a private fields same as the private fields in the class A? Or is it illegal to use this statement because B cant inherit the private fields of A?

不,通过调用 super(1,2,3),您所做的只是将 3 个整数值传递给基础 class 构造函数 public A(int a, int b , int c) 之后,您将这些值分配给私有实例base class 的变量,你没有为 class B 创建一个单独的字段,如果那是你问的,并且 No B class 仍然无法访问 base class 直接实例变量(直接声明我的意思是通过继承或创建实例,还有其他方法,如 setters/getters 等)

And we suppose that we didn't use the super constructor in the class B then normally the computer will call the default constructor of the class A. We know that private fields are not inherited in Java so what will the default constructor initialize in this state ?

不,如果您不使用 B class 中的构造函数,它使用 super(int, int, int) 来匹配基础 class 构造函数 (int a, int b , int c) 的参数那么你的代码甚至不会编译。默认构造函数将调用 Base class 的无参数构造函数,但由于 Base class 没有默认构造函数,您将遇到编译错误!

首先您需要了解一件事:private 父 class 的字段正在被继承。唯一的问题是,如果它们在父级中是 private,则不能直接从子级 class 访问它们(您的示例中的 B class)。所以换句话说:没有一个 B class 方法可以访问这些字段,但是每个 A class 方法都可以访问它们。因此,例如,A class 中可能有一个 public/protected 方法会更改其中一些字段,并且可以从子 class (B).

一旦您将 class 更正为正确的:

class B extends A {
    public B() {
        super(1,2,3);
    }        
}

...我们可以继续回答您的实际问题。

A 的构造函数不创建 字段。这些字段是创建任何 A 对象的一部分,并由构造函数 初始化

这些字段也在 B 中创建,但不是因为您调用了 super(1,2,3),而是因为您扩展了 A。一旦创建了 B 的实例,即 A 的扩展实例 ,这些字段就在那里 - 但它们只能由以下方法访问在 A 本身而不是在其后代中声明。

通过调用 super(1,2,3),您正在初始化那些私有字段。 B 仍然无法访问它们。 A 的构造函数在 B 和这些私有变量之间进行调解。如果您有一个方法可以在 A 中打印这些字段,并且该方法不是私有的,您可以调用它,它会用这些值打印它们。

至于你的第二个问题,如果你没有调用super(1,2,3),Java会尝试调用默认构造函数。但是,对于具有构造函数的 class, 没有默认构造函数。 empty/nullary 构造函数仅在您自己声明或根本未声明任何构造函数时存在。

// The following two classes have a default constructor which will be called
// if any descendent doesn't call super(...)

class HasADefaultConstructor {
}

class AlsoHasADefaultConstructor {

    AlsoHasADefaultConstructor() {
    }
}

// But this one doesn't.

class DoesntHaveADefaultConstructor {

    DoesntHaveADefaultConstructor( String a ) {
    }
}

因此您无法继承私有变量,但如果父 class 具有适当的 getter,则可以访问它们: 运行 这个例子,你看到的输出是 'a is: 1' 关于默认构造函数:在您的示例中,您已明确实现 一个构造函数。所以隐式默认构造函数不再存在

class B extends A {
    public B() {
        super(1, 2, 3);
    }

    public void foo() {
        System.out.println("a is: " + super.getA());
    }

    public static void main(String[] args) {

        B bb = new B();
        bb.foo();

    }

}


class B extends A {
    public B() {
        super(1, 2, 3);
    }

    public void foo() {
        //access a
        System.out.println("a is: " + super.getA());
    }

    public static void main(String[] args) {

        B bb = new B();
        bb.foo();

    }

}

首先,您post输入的代码无效Java。 您 post 工作代码很重要,否则我们无法确定您的要求。

  1. Does the statement super(1,2,3) in the class B create a private fields same as the private fields in the class A? Or is it illegal to use this statement because B cant inherit the private fields of A?

假设您将语句放在构造函数中而不是 class 级别,这是非法的,那么不,不会自动在 class B 中创建字段。它只是调用 superclass A 中的构造函数,该构造函数接受三个 int 参数并初始化对象的 superclass 部分中的字段。

  1. And we suppose that we didn't use the super constructor in the class B then normally the computer will call the default constructor of the class A. We know that private fields are not inherited in Java so what will the default constructor initialize in this state ?

由于 class A 中没有默认(即无参数)构造函数,你会得到一个编译器错误 - 编译器会抱怨 [=31] 中没有合适的构造函数=] A.

Java 仅在 class 中根本未指定构造函数时才自动将无参数构造函数添加到 class。由于 class A 已经有一个构造函数,Java 不会自动添加一个无参数构造函数。