有如下两个类
Father (父类)
package com.yzx.test01;
/**
* 父类对象
*父类初始化<client>
*(1) j=method();(5)
*(2) 父类的静态代码块(1)
*
* 父类的实例化方法:
* (1)super() (最前)
* (2)i=test();
* (3)父类的非静态代码块
* (4)父类的无参构造(最后)
*
* 非静态方法前面其实有一个默认对象this
* this在构造器<或init>它表示正在创建对象,因为这里是在创建Son对象
* 所以test()执行的是子类重写的代码(面向对象多态)
*
* 哪些方法不能被重写:
* final 方法
* 静态方法
* private 等子类中不可见的方法
*
* 对象的多态性
* 子类如果重写了父类的方法 通过子类调用的一定是子类重写过的代码
* 非静态默认的调用对象是this
* this对象在构造器或者说<init>方法中就是正在创建的对象
*
* 类初始化过程:
* (1)一个类要创建实例需要先加载并且初始化该类
* main 方法所在的类需要优先加载和初始化
* (2)一个子类要初始化需要先初始化父类
* (3)
* 一个类初始化就是执行<clinit>
* <clinit>()方法由静态变量显示赋值代码和静态代码块组成
* 类变量显示赋值代码和静态代码块显示赋值从上到下顺序指向
* <clinit>()方法只执行一次
*
*/
public class Father {
private int i = test();
private static int j = method();
//静态代码块
static {
System.out.print("(1)");
}
//构造器
public Father() {
System.out.print("(2)");
}
{
System.out.print("(3)");
}
public int test(){
System.out.print("(4)");
return 1;
}
public static int method(){
System.out.print("(5)");
return 1;
}
}
Son 子类 子类继承父类Father
package com.yzx.test01;
/**
* 子类初始化<clinit>
* (1) j =method();(10)
* (2)子类静态代码块(6)
*
* 先初始化父类:(5)(1)(10)(6)
*
* 子类的实例化方法 <init>:
* (1)super() (最前) (9) (3) (2)
* (2)i=test(); (9)
* (3)子类的非静态代码块(8)
* (4)子类的无参构造(最后)(7)
*
* 因为创建了两个son对象
* 所以<init>方法执行了两次
* (9)(3)(2)(9)(8)(7)
*
*
*
*/
public class Son extends Father{
private int i = test();
private static int j = method();
//静态代码块
static {
System.out.print("(6)");
}
//构造器
public Son() {
System.out.print("(7)");
}
{
System.out.print("(8)");
}
public int test(){
System.out.print("(9)");
return 1;
}
public static int method(){
System.out.print("(10)");
return 1;
}
public static void main(String[] args) {
Son s1 = new Son();
System.out.println();
Son s2 = new Son();
}
}
打印结果:(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
(9)(3)(2)(9)(8)(7)
分析:
类初始化过程:
(1)静态变量显示赋值代码
(2)静态代码块
类实例化过程:
(1)super() 一定在最前
(2)类赋值语句
(3)类非静态代码块
(4)类的无参构造(最后)
特别:
* 对象的多态性
* 子类如果重写了父类的方法 通过子类调用的一定是子类重写过的代码
* 非静态默认的调用对象是this
* this对象在构造器或者说<init>方法中就是正在创建的对象