1.前言
上一讲我们讲到,面向对象的三大特性中的前两个,封装与继承。今天我们就来对这三大特性中的最后一个多态进行介绍。
2.多态
观其名,而知其意,多态,自然为多种形态了。是什么的多种形态呢?我们一直在讲类与对象。那么这个多种形态指的就是一个对象有多种形态了,能够构建多种形态,其基础就是封装与继承的实现。在java中,这多种形态,我们可以理解成两种,向上转型和向下转型。在此之前,我们先来了解什么是编译类型和运行类型。
2.1、运行类型
我们前面说过,一个对象在被new出来时,会在内存中开辟一个地址空间,这个空间的类型便是运行类型。系统是怎么知道这个空间应该创建成这个类型呢?这涉及到了class类的内容,我们在之后会讲解,现在只需要记住,new出来的空间的类型就是运行类型。如图:
a指向的空间便是一个A类型的空间,那么a的运行类型就是A。
2.2、编译类型
编译类型就相对好理解了,编译类型就是对象名左边的类型。
此时,a 左边的Node 便是a的编译类型。
2.3、编译类型与运行类型
以一个滑稽的例子来讲解,一个人的亲生父母是不能改变的,但是养父母可以改变。而编译类型就像亲生父母一样,一个对象的编译类型在它创建的时候已经确定了,不能在把他改成别的类型了。但是呢,运行类型却是可以改变的,如图:
2.4、向上转型
为什么运行类型能够改变?由运行类型的改变,我们引出了向上转型的概念。我不喜欢阐述概念,所以我们重点说明,向上转型就是父类引用指向子类对象。这里有一个引用的概念,引用是指某一个变量定义时指向的地址,所以我们称,该对象引用了改地址,该对象指向了改地址。回到正题。
向上转型就是父类引用指向子类对象。如何理解:如图所示:
我们可以看到,A与B之间存在着一个继承关系,A是B的父类,B是A的子类。此时当我们创建一个A对象时,并不让a引用A类型的空间,而是引用了B类型的空间。此时我们就称为向上转型。
向上转型有什么特点呢?
前面我们说过,编译类型是亲生父母,该父母是高身高,当我们的小a被抱养了,即运行类型指向其他类型,但a的形状特征会像亲生父母而不是养父母,养父母有的特点,a不可能有。
2.5、向下转型
什么是向下转型,就是将一个向上转型的对象转成编译类型为子类形的对象,你不是说过,编译类型是不能够改变的吗?为什么这里就改变了呢?如果你有这样的疑问,说明你对亲生父母和养父母的例子还是不够理解,这里就相当于亲生父母将孩子从养父母处带回去了。但是,无论是养父母养育还是亲生父母养育,这个孩子的血缘是来自哪里呢?
向下转型即子类类型 引用名 = (子类类型)父类引用;这是不是很像强转呀。
受制于本人的表达,具体内容以图解:
所以要先有向上转型,才能有向下转型哦。请牢记!