一、代码展示
public class Father {
private int i = test();
private static int j = method();
static {
System.out.print("(1)");
}
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;
}
}
public class Son extends Father{
private int i = test();
private static int j = method();
static {
System.out.print("(6)");
}
Son() {
System.out.print("(7)");
}
{
System.out.print("(8)");
}
@Override
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)
调用顺序
main方法->父类被调用的静态方法->父类的静态代码块->子类被调用的静态方法->子类的静态代码块—>子类被调用的非静态方法—>父类的非静态代码块—>父类构造方法—>父类中被子类重写的方法(在这里就是指父类中的 int i = test();)—>子类的非静态代码块—>子类的构造方法
为什么(9)出现了两次?
因为非静态方法前面其实有一个默认的对象this,this在构造器(或
)它表示的是正在创建的对象,因为此时是子类的test()运行,这里父类的i=test() 执行的是子类重写的test()方法
为什么第二次执行少了几个步骤
因为(5)(1)(10)(6)是静态方法,只会执行一次
二、类的初始化过程
- 一个类要创建实例需要先加载并初始化该类
- main方法所在的类需要先加载和初始化
- 一个子类要初始化的时候需要先初始化父类
- 一个类初始化就是要执行
()方法 ()方法由静态类变量显示赋值代码和静态代码块组成 - 类 变量显示赋值代码和静态代码块从上到下顺序执行
()方法只执行一次
基本执行流程
- 主要是按照代码顺序执行静态方法->父类被调用的静态方法->父类的静态代码块—>子类被调用的静态方法—>子类的静态代码块—>子类被调用的非静态方法—>父类的非静态代码块—>父类构造方法—>父类中被子类重写的方法(在这里就是指父类中的 int i = test();)—>子类的非静态代码块—>子类的构造方法
三、实例初始化过程
实例初始化就是执行()方法
下面所指的实例对象可以理解为 A a = new A(),这就是创建一个实例对象
1、() 方法可能重载有多个,有几个构造器就有几个 方法
2、()方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
3、非静态实例变量显示赋值代码和非静态代码块 代码从上到下顺序执行,而对应构造器的代码最后执行
4、每次创建实例对象,调用对应构造器,执行的就是对应的()方法
5、方法的首行是super()或super(参数列表),即对应父类的 方法 四、方法的重写
override
- 主要是按照代码顺序执行静态方法->父类被调用的静态方法->父类的静态代码块—>子类被调用的静态方法—>子类的静态代码块—>子类被调用的非静态方法—>父类的非静态代码块—>父类构造方法—>父类中被子类重写的方法(在这里就是指父类中的 int i = test();)—>子类的非静态代码块—>子类的构造方法
哪些方法不可以被重写
- final方法
- 静态方法
- private等子类中不可见的方法
对象的多态
Override和overload的区别
- Override重写的要求?
- 方法名 :相同
- 形参列表:相同
- 返回值类型:相同
- 抛出异常列表:相同
- 修饰符:可以子类可以扩大访问权限
- overload的要球
- 方法名:相同
- 形参列表:必须不同
- 返回值类型:可以不同
- 抛出异常列表:可以不同
- 修饰符:可以不同
- 注意:
- 如果某一方法在父类中是访问权限是 private,那么就不能在子类对其进行重载;如果定义的话,也只是定义了一个新方法,而不会达到重载的效果
- Override重写的要求?
- 了解《JVM虚拟机规范》中关于
和 方法的说明,invokespecial指令。 - 什么是实例,什么是对象?
- 对象是抽象的说法,你可以把它看作一个符合它自身定义的所有实例的代表,而实例则是对象的现实体现。你可以说一个实例是一个对象,但你不能说一个对象是一个实例。因为定义对象时只是把自身的规则和逻辑定义好,实例可以通过输入不同的数据使得自己和其他实例不同。
- 比如:你可以定义一个Wheel.java,它是对象;而Test.java中可以定义两个wheel的实例
- Wheel wheel1 = new Wheel(3); 这个是一个Wheel实例
- Wheel wheel2 = new Wheel(5); 这个是另一个Wheel实例