Java中的虚函数实现父类:定义子类实现

介绍

java语言是一种支持单继承的语言。子类继承超类。如果子类和超类有同名的方法,调用的时候一定要用作用域来调用,否则容易出问题。有些业务场景不需要我们这么复杂,这违背了业务的初衷。我们不想用函数来限制我们的使用。这时候我们可以在方法前加上virtual关键字,使方法成为虚函数。

什么是虚函数

虚函数是要在类中声明,在其基类中声明为虚拟,并在多个或一个派生类中重新定义的函数。

java中是否有虚函数,直接看代码。

定义父类:

定义一个子类来实现超类:

进行测试:

从上面的代码中,我们定义了一个指向不同对象的指针,实际上实现了多态性。我们可以得出结论,java中的函数如果没有被static和native修改,它就是一个虚函数。它本身具有虚函数的性质,即多态性。

不信我们可以看编译后的字节码进行分析

分析表明,对于A.FUN来说,确实使用了虚函数,所以我们可以将Java中的普通函数定义为虚函数。

对象的大小通常由数据成员的大小之和决定。如果声明的类包含虚函数,编译器默认会为这个函数添加一个隐藏数组指针。

所以子类和父类都会有这样一个隐藏成员,它会指向这个虚函数表。如果子类没有对继承父类的功能做任何改变,那么它们的虚函数表的内容是一样的。函数的内容发生了变化,所以它们的虚函数的内容会有所不同。

覆盖、重载和隐藏

Java中的重载是指多个方法的名称相同,但参数列不同。覆盖意味着父类和子类的方法名相同,参数列也相同。隐藏表示父子方法名相同,参数列不同。在 Java 中,死去的父级和子级都存在相同的静态方法。父类的同名方法和属性在形式上是不存在的,但实际上还是存在的。

如何创建和继承虚函数表

基类的函数表的创建往往是根据函数的声明顺序,按顺序编码,然后创建虚函数表,按照它的顺序,当子类继承父类时,子类也会复印。如果子类重写了父类的函数,重写后的函数指针会被更新。添加虚函数的声明时,虚函数的地址是子类的虚函数表的后面。

执行虚函数步骤

注意如果没有覆盖虚函数,虚函数表只有在使用虚函数时才存在,如果子类隐藏了父类的方法,子类将无法访问父类的同名方法。派生类构建时,基类部分会建立自己的虚表,然后派生类会覆盖基类部分表中自己重写的虚函数,然后如果派生类有新的虚函数,同样在这张表中,方法名相当于虚拟表的索引,直接调用索引中的函数。由于Java虚拟机的机制如果没有覆盖虚函数,它的效率将比C++高数百倍。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论