一、什么是多态?
在理解这个概念之前,我们先看下面的一段代码
父类代码:
/**
* 父类代码
*
* @author Administrator
*
*/
public class Common
{
public void test(String name)
{
System.out.println("这是父类方法的名字:" + name);
}
public void test(int age)
{
System.out.println("这是父类方法的年龄" + age);
}
public void test()
{
System.out.println("这是父类方法");
}
}
子类代码:
/**
* 继承common类的子类
*
* @author Administrator
*
*/
public class Rector extends Common
{
public void test(String name)
{
System.out.println("这是子类方法的名字:" + name);
}
public void test(int age)
{
System.out.println("这是子类方法的年龄:"+age);
}
public static void main(String[] args)
{
Common[] arrAyCommons=new Common[2];
Common common = new Rector();
Common Common2=new Common();
arrAyCommons[0]=common;
arrAyCommons[1]=Common2;
for (Common e : arrAyCommons)
{
e.test(20);
}
}
}
执行结果:
因为Common common = new Rector()这行代码是将子类对象赋予父类变量,因此导致了父类变量e即可能指向父类对象也可能指向子类对象,因此当一个变量可以指向多个实体对象的现象我们就称为多态
二、动态绑定
指在运行期间才能确定执行哪个方法的现象称为动态绑定
三、动态绑定的理解
1.上述代码中有e.test(20)这样一行调用方法的代码,以其来做动态绑定的理解
2. 调用方法名为test.参数类型是int,变量e的声明对象可能是Common类也可能是Rector类
3.首先类会被编译器编译成Class文件,然后才会被执行
4.因此编译器会获取Common类中的test方法以及Retor类中test方法形成一个方法集合
5.而后根据参数类型 int类,从方法集合中找到对应完全匹配的方法,即确认要执行的方法是test(int age),这个过程称为重载解析;若没有匹配上,那么编译就会报错
6.运行时根据e的实际类型来找到对应的最合适的类来执行方法,即e的实际类型是Rector类,那么就是调用Rector类的test(int age)方法,若Rector类中不存在该方法,则从其超类Common中确认而后执行Common类的test(int age)方法,以此类推
流程图为:
三、静态绑定
当方法的修饰符为private,static,fina或者调用构造器的时候,编译时就会明确知道是调用哪个类的方法,因此不存在动态的情况,称为静态绑定四、方法调用的最终过程:
1.试想若是每个方法都要按照上述流程,那么意味着每次方法调用都要全类搜索,比较浪费时间
2.JAVA虚拟机会把每个类的方法在其定义时就形成该类的方法表
3.当方法修饰符为private/static/fnal的时候,编译器根据变量的声明对象确认执行该类的方法
4.当方法修饰符为public时,编译器根据变量的声明对象找到对应类的方法表,若该类没有父类,那么直接根据方法签名确认执行该类的方法,若该类存在超类,则在获取超类的方法表,而后根据签名及变量的实际引用对象执行方法
5.方法签名是指方法的名称和方法参数列表,同类中不能有相同的方法签名
五、多态依赖的条件
多态的三要素条件是继承、实现 、重写
1、继承和实现可以使得子类对象赋予父类变量,因此父类变量可以指向多个实际对象
2、重写是指方法重写,即覆盖父类方法,试想若父类有a方法,子类不覆盖的话,那么编译时则会直接确认执行父类的a方法而不会到运行期在来动态选择的