Java中的继承和构造函数

时间:2015-01-06 12:56:24

标签: java inheritance constructor

在以下示例中:

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. super(1,2,3)中的语句class B是否创建了与A类中的私有字段相同的私有字段?或者使用此语句是否合法,因为B不能继承A?
  2. 的私有字段
  3. 我们假设我们没有在B类中使用超级构造函数,那么通常计算机将调用类A的默认构造函数。我们知道私有字段不是在Java中继承的,所以默认构造函数初始化的是什么在这种状态?

5 个答案:

答案 0 :(得分:8)

您无法像这样致电super()

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

super() OR this()应该是构造函数中的第一个语句。首先纠正你的这个基本错误,然后再继续。

super()

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

修改

我没有注意到有人编辑了您在构造函数中添加class B extends A { B (){ super(1,2,3); } } 的问题,现在回答您的问题如下:

  

B类中的语句super(1,2,3)是否创建了与A类中的私有字段相同的私有字段?或者使用此语句是非法的,因为B不能继承A?

的私有字段

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

  

我们假设我们没有在B类中使用超级构造函数,那么通常计算机将调用类A的默认构造函数。我们知道私有字段不是在Java中继承的,那么默认值是什么构造函数在这种状态下初始化?

不,如果您不使用B类中的构造函数,该构造函数使用B来匹配基类构造函数super(int, int, int)的参数,那么您的代码将赢得&#t; t甚至编译。默认构造函数将调用Base类的no-args构造函数,但由于Base类没有默认构造函数,因此您将收到编译错误!

答案 1 :(得分:1)

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

答案 2 :(得分:1)

首先,您发布的代码不是有效的Java。发布工作代码 非常重要,否则我们无法确定您的要求。

  
      
  1. B类中的语句super(1,2,3)是否创建了与A类中的私有字段相同的私有字段?或者使用此语句是否合法,因为B不能继承A?
  2. 的私有字段   

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

  
      
  1. 我们假设我们没有在B类中使用超级构造函数,那么通常计算机将调用类A的默认构造函数。我们知道私有字段不是在Java中继承的,所以默认构造函数初始化的是什么在这种状态?
  2.   

由于类A中没有默认(即无参数)构造函数,因此会出现编译器错误 - 编译器会抱怨类A中没有合适的构造函数。

如果您没有在类中指定构造函数,Java只会自动向类中添加无参数构造函数。由于类A已经有了构造函数,因此Java不会自动添加无参数构造函数。

答案 3 :(得分:0)

一旦你的课程改正了:

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

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

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

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

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

至于你的第二个问题,如果你没有调用A,Java会尝试调用默认构造函数。但是,对于具有构造函数的类,没有默认构造函数。只有在您自己声明或者根本没有声明任何构造函数时,才会存在空/无效构造函数。

super(1,2,3)

答案 4 :(得分:0)

因此,您无法继承私有变量,但如果父类具有适当的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();

    }

}