• 《Java编程思想》学习02:继承类的初始化加载顺序分析


    《Java编程思想》学习02:继承类的初始化加载顺序分析

    本文根据源码实例,分析继承类初始化的加载顺序;

    参考《Java编程思想》第十章

    思路:创建三个类动物Animal类、狗狗Dog类、哈士奇Huskie类,每个类中有一个非静态变量和无参构造函数,且Huskie类继承Dog类,Dog类继承Animal类;然后实例化一个Huskie类对象,根据输出的日志确认加载顺序

    源码

    Animal类

    package com.tyj.study.thinkinjava.chapter8;
    
    /* *
     *@Description:
     *@Author:TYJ
     *@Date: create in  2019/7/10 8:59
     */
    
    public class Animal {
    
        private Double weight = getWeight();
    
        private Double getWeight() {
            System.out.println("i am Animal getWeight method");
            return new Double(1.0);
        }
    
        public void eat(){
            System.out.println("i am Animal eat method");
        }
    
        public Animal() {
            System.out.println("i am animal constructor");
            eat();
        }
    
        public static void main(String[] args) {
            Animal animal = new Animal();
            /**
             日志输出:
                 i am Animal getWeight method
                 i am animal constructor
                 i am Animal eat method
             */
        }
    
    }

    Dog类

    package com.tyj.study.thinkinjava.chapter8;
    
    /* *
     *@Description:
     *@Author:TYJ
     *@Date: create in  2019/7/10 9:00
     */
    
    public class Dog extends  Animal{
    
        private int legNum = getLegNum();
        private String food = new String("meat");
    
        private int getLegNum(){
            System.out.println("i am Dog getLegNum method");
            return 4;
        }
    
        public void eat(){
            System.out.println("i am Dog eat method. dog eat " + food);
        }
        public Dog() {
            System.out.println("i am Dog constructor");
        }
    
        public static void main(String[] args) {
            Dog dog = new Dog();
            /**
             日志输出:
                 i am Animal getWeight method
                 i am animal constructor
                 i am Dog eat method. dog eat null
                 i am Dog getLegNum method
                 i am Dog constructor
             */
        }
    }

    Huskie类

    package com.tyj.study.thinkinjava.chapter8;
    
    /* *
     *@Description:
     *@Author:TYJ
     *@Date: create in  2019/7/10 9:00
     */
    
    public class Huskie extends  Dog{
    
        private Boolean isStupid = judgeIQ();
        private Boolean isLovely = judgeLovely();
        private Boolean judgeIQ(){
            System.out.println("i am Huskie judgeIQ method");
            return true;
        }
        private Boolean judgeLovely(){
            System.out.println("i am Huskie judgeLovely method");
            return true;
        }
    
        public Huskie() {
            System.out.println("i am Huskie constructor");
        }
    
        public static void main(String[] args) {
            Huskie huskie= new Huskie();
            /**
             日志输出:
                 i am Animal getWeight method
                 i am animal constructor
                 i am Dog eat method. dog eat null
                 i am Dog getLegNum method
                 i am Dog constructor
                 i am Huskie judgeIQ method
                 i am Huskie judgeLovely method
                 i am Huskie constructor
             */
        }
    }

    分析

      1-分析Animal类的main方法,可以确认,实例化一个普通类,会先初始化变量,再调用构造函数;(更具体的分析,请参考本人上一篇博客:《Java编程思想》学习01:普通类的初始化加载顺序分析》

      2-分析Huskie类的main方法,实例化一个子类,会递归找到最最上层的父类,然后按照继承的顺序初始化,本案例中,会依次初始化Animal类,Dog类,Huskie类;并且在舒适化每一个类的时候,先初始化变量,在调用构造器;

      3-分析Dog类的main方法,输出了"i am Dog eat method. dog eat null",原因是因为Dog类实例化是,调用了父类Animal类的构造器方法,执行了eat();但因为Dog类重写了eat()方法,所以Animal类的构造器调用的是Dog类的eat()方法,但此时Dog类还没有被初始化,所以此时Dog类的food变量的值是null;所以输出"i am Dog eat method. dog eat null";

    总结

      1-实例化一个普通类,会先初始化变量,再调用构造函数;

      2-实例化一个有继承关系的子类,会递归找到最上层的父类,然后按照继承的顺序依次初始化每一个类;

      3-实例化时,如果父类的构造器调用了被子类重写的方法,而子类方法有引用了子类的成员变量,则可能会出现因为成员变量未被初始化就被使用的情况;

      4-目的:在实例化一个子类,必须先实例其对应的父类,以确保子类可以正常调用基类对子类公开的变量和方法。另外,《Java编程思想》给了一个编写构造器的建议:用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其它方法。

  • 相关阅读:
    vim代码对齐
    在liunx中,快速查找到以前使用过的命令行
    linux文件权限与目录设置
    ASP常用代码
    存储过程
    WebService
    SNS
    浪曦博客系统
    SQL事件探查器与索引优化向导
    光盘AJAX
  • 原文地址:https://www.cnblogs.com/wobuchifanqie/p/11161827.html
Copyright © 2020-2023  润新知