Java多态的实现原理概述
面向对象的编程语言的特色就是:封装,继承,多态。作为基本特色之一,多态为我们带来了很多的便利。这篇文章我们将从大体上探究一下多态的实现原理,而不做具体实现细节的分析。
java项目是有一个个类组成的,出于重用以及可扩展的考虑,我们经常讲这些类关联起来,比如继承或是实现。多态也是基于类之间的这种关联来实现的,这也是OOP的精华所在。
当一个类被加载到JVM上时,该类的类型信息就被加载到JVM的方法区中。类型信息一般包括该类的方法代码、类变量、成员变量的定义,变量类型信息等等该类的源码中定义的所有信息。
类与类之间的继承关系也维护在类型信息中,也就是说我们在运行期可以获得类之间的继承实现关系。
一个典型的多态的前提条件为:父类引用指向子类对象。但其实除此之外,还有另外的一个条件:通过该引用调用子类重写父类的的非私有实例方法。
我们可以先讲上面的结论放在一旁,先来研究java中进行函数调用的字节码指令。
在java字节码中,进行函数调用的字节码指令有:
invokestatic
:调用类的静态方法invokespecial
- 调用私有实例方法、构造器方法
- 使用super关键词调用父类的实例方法、构造器
- 调用所实现接口的default方法
invokevirtual
:调用非私有实例方法invokeinterface
:调用接口方法invokedynamic
:调用动态方法(比较复杂,此处不研究)
其中invokestatic
,invokespecial
是静态绑定,即只与自己的调用者声明类型绑定,编译器可以确定;而invokevirtual
和invokeinterface
会进行函数的动态绑定,即在运行期间才与实际类型绑定,也正是这种机制才造就了OOP的多态。
在java多态的典型应用场景中,无论是新建对象还是传参,一般都可以分为以下两个方面:
- 声明类型
- 实际类型
代码如下:
class Greeting {
public void test(){
}
// ...
}
class FrenchGreeting extends Greeting