类初始化和实例初始化

1、类初始化过程

  (1)一个类要创建实例需要先加载并初始化该类

    main()方法所在的类需要先加载和初始化 ---> 此类中main方法中为空 输出也为5 1 10 6

  (2)一个子类初始化要先初始化父类

  (3)一个类初始化就是执行<clinit>()方法 字节码文件中,<clinit>()方法由静态类变量显示赋值代码和静态代码块组成

    变量显示赋值代码和静态代码块从上到下执行

    <clinit>()方法只执行一次

2、实例初始化过程

  (1)实例初始化就是执行<init>()方法

    <init>()方法可能重载有多个,有几个构造器就有几个<init>()方法

  (2)<init>()方法的首行是super()或者super(实例列表),即对应父类的<init>()方法 (最先执行)

     <init>()方法由 非静态类变量显示赋值代码和非静态代码块、对应构造器代码组成

     非静态变量显示赋值代码和非静态代码块从上到下执行,而对应的构造器代码最后执行(顺序执行)

    每次创建实例对象,调用对应的构造器,执行的就是 对应的<init>()方法    (最后执行)

举例:

public class Father {
 
    private int i = test();
    private static int j = method();

    static {
        System.out.println("1");
    }

    Father() {
        System.out.println("2");
    }

    {
        System.out.println("3");
    }


    public int test() {
        System.out.println("4");
        return 1;
    }

    public static int method() {
        System.out.println("5");
        return 1;
    }
}  
 
public class Son extends Father {

    private int i = test();
    private static int j = method();

    static {
        System.out.println("6");
    }

    Son() {
        //super();  写或者不写都存在,在子类的构造器中一定会调用父类的构造器
        System.out.println("7");
    }

    {
        System.out.println("8");
    }

    public int test() {
        System.out.println("9");
        return 1;
    }

    public static int method() {
        System.out.println("10");
        return 1;
    }

    public static void main(String[] args) {
        Son s1 = new Son();
        System.out.println();
        Son s2 = new Son();
    }

}
执行顺序: 
  1、先初始化父类 :
    <clinit>()方法
    (1)j = method()
    (2)静态代码块
    父类的静态类变量显示赋值代码和静态代码块 --> 5 1
  2、再初始化子类 :
    <clinit>()方法
      (1)j = method()
      (2)静态代码块
       子类的静态类变量显示赋值代码和静态代码块 --> 10 6
  3、子类的实例化方法
    (1)super() 父类的实例初始化 --> 9 3 2
    (2)i=test() --> 9
    (3)子类的非静态代码块 --> 8
   (4)子类的无参构造 -->7

    创建了两个Son()对象 因此子类的实例化方法执行两遍 --> 9 3 2 9 8 7

  子类的执行结果为:
5 1 10 6 9 3 2 9 8 7
9 3 2 9 8 7
  父类的初始化
    (1)j = method()
    (2)静态代码块
  父类的实例初始化
    (1)super()
    (2)i=test()
    (3)子类的非静态代码块
    (4)子类的无参构造
  注意:非静态方法前面其实一直有一个默认的对象this
     this在构造器或者<init>()方法中,他表示正在创建的对象,因此i=test()执行的是子类重写的代码(面向对象多态)
      这里的i=test()执行的是子类重写的test()方法

3、方法的重写

  (1)、哪些方法不可以被重写
     final方法、静态方法、private等子类中不可见的方法
  (2)、对象的多态性
     子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
     非静态方法默认的调用对象是this
     this对象在构造器或者<init>()方法中就是正在创建的对象

4、overload和override的区别

名词
Overload方法的重载
Override方法的重写
位置
同一个类中 
在父子类中
方法名
必须相同
必须相同
形参列表
必须不同
必须相同
返回值类型
无关
void和基数类型:一致;引用类型<=
抛出的异常列表
无关
<=
权限修饰符
无关(建议一致)
>=

 


   

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-07-13 15:46  TIMEAWAY  阅读(439)  评论(0编辑  收藏  举报