三、Java基础---------关于继承、构造函数、静态代码块执行顺序示例讲解

时间:2021-12-11 15:42:09

     在上节博客中曾提到过类的继承,这篇文章主要是介绍类的继承、构造函数以及静态代码块的执行顺序。

    首先接着分析在黑马基础测试中的一个关于继承的题目,题目描述如下:

声明类Person,包含2个成员变量:name、age。定义函数sayHello(),调用时输出:我叫***,今年***岁了。声明类Chinese继承Person。

这是一个很基础的题,第一步要构建一个父类:Person,Person包含name、age属性,已经一个成员方法sayHollo()。具体实现如下:

    class Person{//建立父类

    public int age;

    public String name;

    void sayHello(){

        System.out.println("我叫"+this.name+",今年"+this.age+"岁了。");

        }

}

第二步建立子类:

    class Chinese extends Person{//子类继承父类,包括同名属性以及方法

    public Chinese() {//自定义无参构造方法,当new该类时运行

        name="月芽之上";

        age=23;

        this.sayHello();//调用父类成员方法

        }

}

调用方法如下:

     Chinese ch=new Chinese();//建立Chinese实例对象。

建立子类的对象,并开辟堆内存。子类在机场父类时会继承父类的属性以及方法。所以在子类中也有name、age属性,同样子类也有父类的sayHello方法。子类中在给父类属性赋值的时候会覆盖父类的方法(关于覆盖与重写在后续的博客中进行分析),而在new Chinese()时会自动调用Chinese的无参构造方法所以父类的name的值就变为 name="月芽之上",age=23,然后通过this调用当前实例对象的sayHello方法,而这时又会调用父类已经定义了的sayHello方法。值得注意的是,如果子类重写了父类的方法的话,就不会再去调用父类的方法,这是一个常识但是也经常会出错,希望日后自己不会犯这样的错误。

    接下来分析第二个例子。

    题目描述:

1、建立一个Cat父类,包含nameage属性,无参构造函数、有一个参数的构造函数,以及get,set方法

2、建立子类HelloKitty,继承Cat,子类包含静态代码块、无参构造方法、一个参数的构造方法。具体程序描述如下:

    public class Cat {

    private String name;

    private String age;

    static {

        System.out.println("这个基本上是最难得继承题");

    }

    public Cat() {

        System.out.println("父类无参构造");

    }

    public Cat(String name) {

        this.name = name;

        System.out.println("父类cat构造方法");

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getAge() {

        return age;

    }

    public void setAge(String age) {

        this.age = age;

    }

}

子类:

    public class HelloKitty extends Cat {

    static {

        System.out.println("你猜我在哪里执行");

    }

    public HelloKitty(String name) {

        super(name);

        System.out.println("子类构造器有参方法");

    }

    public HelloKitty() {

        System.out.println("我执行子类无参构造函数");

    }

}

       

          

测试方法1

Cat cat = new Cat();

System.out.println(cat.getAge());

执行过程分析:

建立父类对象并指向父类的引用,在new Cat()时会自动调用Cat的无参构造函数,而静态代码块优于构造方法而执行,因此结果如下:

            

这个基本上是最难得继承题                     父类静态代码块

父类cat构造方法                            父类无参构造函数

Null                                     字符串初始值为null

          

测试方法2

          

Cat cat = new HelloKitty();

System.out.println(cat.getAge());

执行过程分析:

建立父类对象指向子类的引用,在new HelloKitty()调用子类的无参构造函数,而在执行子类无参构造函数之前会调用父类的无参构造函数,而静态代码块是由于构造函数的,因此第一步先执行父类的静态代码块,第二步执行子类的静态代码块,第三步执行父类的无参构造函数,第四步执行子类无参构造函数,第五步调用getAge()方法。

          

这个基本上是最难得继承题            父类静态代码块

你猜我在哪里执行                     子类静态代码块

父类无参构造                        父类无参构造函数

我执行子类无参构造函数                子类无参构造函数

Null                                字符串初始值为null

       

    测试方法3

Cat cat = new HelloKitty("helloKitty");

System.out.println(cat.getAge());

执行过程分析:

建立父类对象指向子类的引用,在new HelloKitty("helloKitty")调用子类的有参构造函数,而子类带参数的构造函数中调用了父类的带参数的构造函数,因此先执行父类的静态代码块,然后执行子类静态代码库,然后执行父类带参数的构造函数,然后执行子类的带参数的构造方法,最后调用getAge()方法。

       

这个基本上是最难得继承题            父类静态代码块

你猜我在哪里执行                     子类静态代码块

父类cat构造方法                    父类带参数构造函数

子类构造器有参方法                    子类带参数构造函数

Null                                字符串初始值为null

       

到此,关于继承、构造函数、静态代码块的执行顺序相关知识点介绍完毕,谢谢您的阅读。