多态
-
分类
- 静态多态(编译时多态):编译时决定采取哪种方式。例如重载(同一个类中同名同返回值不同参的函数)。
编译时类型:声明时所用的类型。 - 动态多态(运行时多态): 运行时决定采取哪种方式。例如覆盖(父子类有同名同返回值同参的函数)。
运行时类型:指向的对象的类型。 - 例:Person p=new Student();
其中Student extends Person,那么p的编译时类型是Person,运行时类型是Student
- 静态多态(编译时多态):编译时决定采取哪种方式。例如重载(同一个类中同名同返回值不同参的函数)。
-
动态多态的运行时绑定
- 被隐藏的属性,子类对象被转换成父类后,访问的是父类的属性(编译时类型决定)
- 被覆盖的方法,子类对象被转换成父类后,访问的是子类的方法(运行时类型决定)
由几个例子总结的:
- 父类和子类有同名属性(隐藏),编译时类型和运行时类型都是子类的情况下:
调用父类的方法,则访问父类的该属性。
调用子类的方法,则访问子类的该属性。
直接用.访问该对象的该属性,访问的是父类的该属性。 - 父类和子类有同名属性和同名方法(隐藏&覆盖),编译时类型是父类而运行时类型是子类的情况下:
对象.调用该同名方法,则调用的是子类的该方法,在方法里访问的也是子类的该属性。
调用父类的其他方法来访问该属性,则访问的是父类的该属性。
直接用.访问该对象的该属性,访问的是父类的该属性。
对于有static关键字的:
- 是被所有实例所共享的
- static方法是非虚的,以声明的类型为准(编译时类型),与实例类型无关
- 如果父类有一个static方法/属性,且子类也有一个一模一样的static方法/属性,那么在编译时类型是父类而运行时类型是子类的情况下,调用/访问的是编译时类型的static方法/属性。
3种非虚的方法:
- static
- private(子类看不见)
- final(子类不能覆盖)