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会先调用父类的构造方法,然后继续执行子类构造方法额外的部分。

java中父类在子类中创建父类对象是不是也会掉用对应子类的构造函数?
Circle c = new Circle(4.0);你可以试下吧这行代码也注释掉,你会发现不new 父类对象一样会报错。现在来说说编译报错的原因。首先说两点:子类构造方法会调用父类构造方法 如果不写构造方法,java是默认了创建一个无参构造方法。而一旦自定义了一个构造方法,那么不论这个构造方法的参数情况是怎样的...

JAVA中 子类与父类构造方法的关系 个人理解
可以无构造方法:仍会默认调用super()也可以有构造方法:其中会默认地调用super(),你也可以在开头加上这句,如果你不希望调用父类默认的无参方法,那么在 子类构造方法 中调用 父类含参构造方法。上述看似情况复杂,其实基于其原则理解并不难。综上:java为了保持 子类的构造基于父类的构造 这...

子类都会首先调用父类的构造函数吗?
不是的,子类可以无条件调用父类的无参数构造函数,如要调用有参数构造函数的话需要显式调用,但如果子类中没有显式调用父类的构造函数时,会调用父类编译器自动给加上的无参构造函数,你可以通过反编译看到父类中多了一个无参的构造函数。如何调用父类的构造函数 es6 E9 和 IE10。原因是 ocs 实...

JAVA实例化子类时候同样也实例父类,O bject是所有类的父类,难不成实 ...
不会产生父类对象,只是用了父类的构造函数而已,并不是用到构造函数就会产生对象,构造函数只是起对象初始化作用的,而不是起产生对象作用的。继承是:父类中的成员被继承到子类对象中,用指向子类对象的父类引用调用父类成员,只不过是从 子类对象内存空间中找到那个被继承来的父类成员。

为什么在实例化子类的对象的时候会调用先调用父类的构
因为子类继承父类之后,获取到了父类的内容(属性\/字段),而这些内容在使用之前必须先初始化,所以必须先调用父类的构造函数进行内容的初始化.

java中 子类 一定要调用父类的所有构造方法吗?
不是~~但是至少应该调用一个!也可以全部调用的!任意一个类都拥有构造器的!如果你自己没有写,系统会给你加上一个默认的,没有参数的构造器,如果你自己写了,系统不会给你加上去的!因为继承就是要把父类的东西拿给自己,并在此基础上扩充自己!子类在调用构造器的时候,不知道父类拥有什么,所以...

在JAVA 中为什么在父类中定义了一个构造函数,而在其子类中却一定的要...
子类不一定非要写一个构造函数。(1)如果你有需要加入参数来构造一个类实例的话,那你就可以写一个,但是写前需要第一句是“super();”这是调用父类的构造方法。(2)如果你没有特定的要求,那就可以不写,java虚拟机会在编译的时候给你自动添加一个无参数的构造方法。下面是写构造方法的注意...

java关于子类和父类构造方法的关系,犯迷糊!!
1、父类中没有显式定义任何构造方法,此时父类中实际有一个默认的无参数构造方法。这时,在子类中显式定义任何构造方法时,可以不用使用super调用父类的默认方法。2、父类中显式定义了默认的无参数构造方法,那么子类可以定义任意的构造方法,而不必使用super调用父类的构造方法 3、父类中显示定义了...

java中子类自动继承父类的无参构造方法吗?
首先子类中的方法必须调用父类的构造方法,如果父类中只有一个有参的构造方法,你在子类的构造方法必须调用,而且是子类的构造方法第一句话必须是调用父类的有参构造方法,否则编译器会提示错误的。如果父类中有无参的构造方法,你没有写的话会自动调用的 ...

...父类中无参的构造函数,然后在调用子类的构造函数,这句话什么意思_百...
public static void main(String[] args) throws IOException { B b = new B();} } class A{ public A() { System.out.println("A类的无参数构造方法");} } class B extends A{ public B() { \/\/这里面不写,系统也会默认的调用super(),即父类的无参构造。\/\/不管子类的无参构造还是...

相似回答