在Java继承中,构造函数的分析。

    在Java中,构造函数常常用于初始化操作,将一些初始化操作放入构造函数中,是大家一种常用的方法。
那么在Java的继承中,构造函数又是怎么一会事呢,在这里总结一下:

一、理论分析

(1) 一个类(如:ClassA),如果没有声明任何构造函数,那么系统会自动生成一个无参构造函数,此时使用ClassA myClass
= new ClassA(),不会报错。但是,如果显式声明了一个有参构造函数,却没有声明一个无参构造函数的话,系统不会自动生成
一个无参构造函数,此时,再使用ClassA myClass = new ClassA()就会报错。如果要消除报错,则必须使用有参构造函数,
或者添加一个无参构造函数。所以,一个类的构造函数,一般只有三种状况:无参 或者 无参 + 有参 或者 有参

(2) 在继承关系中,子类的所有构造函数(包括无参构造函数(默认构造函数),有参构造函数等),如果不显式声明调用哪种
super,那么都会默认调用super(),即都会默认调用父类的无参构造函数(默认构造函数)。而,如果父类此时没有无参构造
函数存在的话,就会报错。为了修改报错,只能显式调用父类显式声明的构造函数之一或者在父类中增加无参构造函数。

(3) 在继承关系中,当使用new一个类时,程序的执行顺序为:首先执行父类的构造函数方法,再执行自身的构造函数方法,
这个执行顺序不可更改,否则报错或不能运行。

(4) 在深度继承关系中,即当存在C继承B,B继承A,或者更多层继承时,首先执行最上层的构造函数,再依次顺着继承链传递下去,
一直到创建对象的那个类。例如:我们声明C对象时,调用的是C的构造函数c,构造函数c调用的是父类B的构造函数b,构造函数b调用
的是父类A中的构造函数a,那么执行结果就是:a => b => c 。

二、实践操作

为了验证理论,我们进行了操作实践,下面提供实践代码,亲自实践之后,才会深刻懂得继承中,构造函数的关系。
代码说明:继承关系为ClassC继承ClassB,ClassB继承ClassA。Test为执行测试类。

ClassA的代码
public class ClassA {

    public ClassA() {
        System.out.println("父类的无参构造函数。");
    }

    public ClassA(String string){
        System.out.println("父类的有参构造函数");
    }

}
ClassB的代码
public class ClassB extends ClassA {
    public ClassB(){
        super(null);
        System.out.println("子类的无参构造函数");
    }

    public ClassB(String str){
        System.out.println("子类的有参构造函数");
    }

}
ClassC的代码
public class ClassC extends ClassB{

    public ClassC(){
        System.out.println("孙子的无参构造方法");
    }

    public ClassC(String string){
        System.out.println("孙子的有参构造方法。");

    }
}
Test的代码
public class Test {
    public static void main(String[] args) {

        String string = "Hello World";
        ClassA myClasss0 = new ClassA();
        System.out.println("******************");
        ClassA myClass1 = new ClassA(string);
        System.out.println("*****************");
        ClassB myClass2 = new ClassB();
        System.out.println("*****************");
        ClassA myClass3 = new ClassB(string);
        System.out.println("**********************");
        ClassA myClass4 = new ClassC();
        System.out.println("*********************");
        ClassB myClass5 = new ClassC(string);

    }

}

三、疑问解答

    有的人可能有这样的疑问,既然子类的方法可以覆盖重写父类的方法,那么子类的构造函数是不是也可以覆盖重写
父类的构造函数啊?

    答案当然是否定的,子类的构造函数不能覆盖重写父类的构造函数。首先,java中子类无法继承父类构造函数,因此不能重写父类构造函数。
那有的人可能会问,既然子类没有继承父类的构造函数,那为什么会自动调用父类的构造函数啊?其实,如果你没有显式通过super来调用父类
指定的构造函数,那么系统会自动帮助我们调用父类默认的构造函数,即super()。所以说,子类不能继承父类的构造方法,更不能覆盖
父类的构造方法。

    或者,换个角度想一下,子类覆盖父类的方法需要两者的方法完全一致(权限修饰符除外),而且子类方法的权限要高于父类方法的权限,
而,子类和父类的类名不通,构造方法就不存在着所谓的覆盖复写,我们只能在子类中调用父类的构造方法来初始化,
也必须调用父类的构造函数进行初始化。而且,super必须是子类构造方法中的头一条语句。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值