引言
- 最近研究了一下java中的多态这一java特有的非常优秀的特性;
- 多态增加了程序的灵活性和可扩展性,但是也对程序的安全性和稳定性提出了挑战;
多态的概念
- 多态的定义:指允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用);
- 多态的分类:编译时多态(方法的重载就是其具体实现),运行时多态(本文中的多态均指运行时多态);
- 实现多态的技术是动态绑定(dynamic binding):是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法;
- 多态的作用:消除类型之间的耦合关系;
多态存在的条件
- 要有继承(包括接口的实现);
- 要有重写;
- 父类引用指向子类对象;
实例
- 父类如下:
1 | package test11; |
- 子类如下:
1 | package test11; |
BaseClass base = new BaseClass();
定义base为父类,可访问所有父类的变量和方法;SubClass sub = new SubClass();
定义为子类,优先访问子类中的变量和方法,如果没有,再从父类寻找;- 对于
BaseClass bc = new SubClass();
:- 编译时,系统首先new出来一个SubClass类的实例,系统自动将这个new出来的实例强制转换为BaseClass类型,并且赋给bc对象;
- 运行时,bc对象名义上是BaseClass类型,实际上是SubClass类型,bc对象可访问且优先访问SubClass类中的方法,找不到的话再到它的父类BaseClass寻找;
- 尽管bc对象在运行时是SubClass类型,bc对象在运行时是可以访问SubClass自己的方法的(比如sub()方法),但是由于bc对象在编译时是BaseClass类型,bc.sub()这一句话根本通不过编译,所以运行时bc对象实际上是不能访问sub()方法的;
- 在编译时,base和bc对象都是BaseClass类型的对象,但是在运行时base仍为BaseClass类型,bc却是SubClass类型,这就出现了base和bc这两个编译时相同类型的变量,在运行时调用test()方法的结果却不一致的现象,就是多态;
- 多态性只对方法有效,对于变量无效,所以访问bc对象的a变量时,输出父类的a变量而非子类的a变量值,这和java内部运行机制有关;