java中父类在子类中创建父类对象是不是也会掉用对应子类的构造函数?

class Circle{

double r; //半径

public static double pi = 3.14; //固定不变的

public Circle(double r){
this.r = r;
}

//计算面积
public final void getArea(){
System.out.println("圆形的面积是:"+r*r*pi);
}
}

class Demo2 extends Circle
{

public Demo2(double r){

super(r);
}

public static void main(String[] args)
{

Circle c = new Circle(4.0);
}

}
//注释掉子类的构造方法后编译失败这是为什么

在子类中创建父类对象的实例不会调用子类的构造函数

你这里注释掉子类构造方法报错不是因为

Circle c = new Circle(4.0);

你可以试下吧这行代码也注释掉,你会发现不new 父类对象一样会报错。

 

现在来说说编译报错的原因。

首先说两点:

    子类构造方法会调用父类构造方法

    如果不写构造方法,java是默认了创建一个无参构造方法。而一旦自定义了一个构造方法,那么不论这个构造方法的参数情况是怎样的,默认的无参构造方法都不会再创建。

这里父类自定义类一个public Demo2(double r)的构造方法,所以没有无参构造方法了只有这一个构造方法。

子类你也自定义类一个构造方法,然后去调用了父类构造方法,这样没有问题。

如果把子类的构造方法注释掉,现在子类没有自定义构造方法了,创建默认构造方法。

public Demo2() {
  super();   // new Circle();
 }

默认无参构造方法去调用父类的无参构造方法,但是父类没有无参构造方法,所以报错。

 

你在父类中加一个无参构造方法,就会发现这个错误消失了。

public Circle() {
 }

追问

注释掉Circle c = new Circle(4.0);不会报错哦,
我在想是不是在继承关系中,父类在子类中创建对象时,是不是jvm调用构造函数受到了限制。又正好我发现加了public Demo2(double r){
super(r);又编译成功了,又或者去掉 extends Circle也能编译成功,所以我才会想到是不是调用了子类构造方法去调用父类构造方法。。

追答

注释掉Circle c = new Circle(4.0);依然是会报错的

报错为:Implicit super constructor Circle() is undefined for default constructor. Must define an explicit constructor

就是我前面说的原因,子类Demo2的默认无参构造方法去调用父类Circle的无参构造方法,但父类又没有无参构造方法,所以报错了。

“super constructor Circle() is undefined”

追问

不好意思,现单位空余时间多,我外行自学,刚开始我用的Editplus,我只能看到编译没有报错。我明白了您的意思了,报错和Circle c = new Circle(4.0);无关,关键在子类中要指定调用父类显示的构造函数,或者在注释点子类的构造方法后,要在父类中添加无参的构造函数。。。我是看到一加上extends Circle,然后编译不通过就以为是父类的购造方法限制了

谢谢您

追答

不客气

具体说是子类的构造方法方法需要调用父类的构造方法

这里的调用也有默认值,你可以自定义调用某个父类的构造方法,如果你不指明。比如子类构造方法是这样的:

public Demo2(double r) {
 }

也是没问题的,这时候会默认调用父类的无参构造方法。等价于

public Demo2(double r) {
  super();
 }

当然前提是父类有无参构造方法,不然就会像之前你遇到的那样报错。

忘采纳,谢谢!

温馨提示:答案为网友推荐,仅供参考
第1个回答  2015-09-08
因为父类没有无参数构造方法。所以注释掉子类构造方法就会编译失败。

子类不提供显式的构造方法,编译器会生出一个默认的无参数构造方法,这个方法会调用父类的无参数构造方法,没有就会报错
第2个回答  2015-09-08
java默认的构造方法是无参的,也就是说你注释掉那个构造方法之后,它自己会保留一个默认的构造方法public Demo2(){super();}。而父类由于你没有写无参的构造方法,所以super()这个方法是不存在的,所以会编译失败。
为了防止这种情况发生,一般我们的编程习惯是,如果需要有参的构造方法,那么我们同时也需要定义一个无参的构造方法--这句话同时适用于你的子类和父类。
另外,一个最简单的方法来验证我说的话就是,你在注释掉子类的构造方法的时候同时也注释掉父类的构造方法,然后你在main方法里把4.0去掉,那么编译时可以通过的。追问

不知道你发现我是在子类中创建的父类的对象没?我知道在创建子类对象时是会在注释掉子类的构造方法的时候同时也注释掉父类的构造方法,然后在main方法里把4.0去掉,那么编译时可以通过的。所以我才会问,父类是不是在创建对象的时候,jvm是不是也调用了子类的对应的构造函数去调用父类的构造函数初始化对象。

追答

创建父类对象的时候,跟子类一点关系也没有,JVM只调用父类的构造方法;创建子类对象的时候,JVM会先调用父类的构造方法,然后继续执行子类构造方法额外的部分。

相似回答