首页 > 技术文章 > 【Java】隐藏覆盖与父子类的初始化顺序

Zeiion 2021-04-10 23:20 原文

静态类型与动态类型

静态类型:定义该引用变量的类型;

动态类型:该引用实际指向的对象类型。

比如:A a=new B();

那么,引用a的静态类型就是A,动态类型就是B。

静态绑定与动态绑定

静态绑定:所有依赖于静态类型来将某方法和该方法所在的类关联起来的动作都是静态绑定。因为静态绑定在程序运行前发生,所有又叫前期绑定。

动态绑定:所有依赖于动态类型来将某方法和该方法所在的类关联起来的动作都是动态绑定。因为动态绑定是在程序运行时,通过RTTI实现,所以又叫后期绑定。

类的属性以及 静态方法(final、static、private)的方法是静态绑定

其他方法为动态绑定

@Override

①声明为 final 的方法不能被重写;声明为 static 的方法不能被重写,但是能够被再次声明

②private视为final,但是又有所不同。可以在子类中重写父类的private方法,但是实际相当于一个新创建的方法

③参数列表与被重写方法的参数列表必须完全相同

④方法重写时,访问控制权限不能降低

返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类

隐藏与覆盖

  • 覆盖:(动态绑定的结果)

    • 对于实例方法

    • 子类重写父类的方法,要求方法名和参数类型完全一样(参数不能是子类),返回值和异常比父类小或者相同(即为父类的子类),访问修饰符比父类大或者相同。

  • 隐藏:(静态绑定的结果)

    • 静态方法和属性(静态变量和实例变量)

    • 父类和子类拥有相同名字的属性或者方法( 方法隐藏只有一种形式,就是父类和子类存在相同的静态方法)时,父类的同名的属性或者方法形式上不见了,实际是还是存在的。

父类的成员变量只会被隐藏,而且支持交叉隐藏(比如静态变量被非静态变量隐藏)

父类的静态方法只会被静态方法隐藏,不支持交叉隐藏

父类的非静态方法会被覆盖,但是不能交叉覆盖。

  • 隐藏和覆盖的区别

    (1)被隐藏的属性,在子类被强制转换成父类后,访问的是父类中的属性

    (2)被覆盖的方法,在子类被强制转换成父类后,调用的还是子类自身的方法

    在无强制转换时可以使用super关键字

父子类的初始化

如果其父类还没有被装载过,会先完成父类的装载(加载文件和静态初始化),之后才执行本类的静态初始化。

总的初始化顺序总结如下:

父类静态属性–>父类静态代码块–>子类静态属性–>子类静态代码块–>

父类属性赋值–>父类构造代码块–>父类构造方法–>

子类属性赋值–>子类构造代码块–>子类构造方法

推荐阅读