前几篇文章的例题说明了方法重载机制,但并没有显示它们的作用。实际上,如果方法重载只是一个名字空间的约定,那么它最多是有趣的,但是没有实际价值的。

然而,情况并不如此。方法重载构成Java的一个最强大的概念的基础:动态方法调度。动态方法调度是一种在运行时而不是编译时调用重载方法的机制。动态方法调度是很重要的,因为这也是Java实现运行时多态性的基础。

让我们从重述一个重要的原则开始:超类的引用变量可以引用子类对象。Java用这一事实来解决在运行期间对重载方法的调用。过程如下:当一个重载方法通过超类引用被调用,Java根据当前被引用对象的类型来决定执行哪个版本的方法。

如果引用的对象类型不同,就会调用一个重载方法的不同版本。换句话说,是被引用对象的类型(而不是引用变量的类型)决定执行哪个版本的重载方法。因此,如果超类包含一个被子类重载的方法,那么当通过超类引用变量引用不同对象类型时,就会执行该方法的不同版本。

下面是阐述动态方法调度的例子:

// Dynamic Method Dispatch
class A { void callme() { System.out.println("Inside A's callme method"); }
}
class B extends A { // override callme() void callme() { System.out.println("Inside B's callme method"); }
}
class C extends A { // override callme() void callme() { System.out.println("Inside C's callme method"); }
}
class Dispatch { public static void main(String args[]) { A a = new A(); // object of type A B b = new B(); // object of type B C c = new C(); // object of type C A r; // obtain a reference of type A r = a; // r refers to an A object r.callme(); // calls A's version of callme r = b; // r refers to a B object r.callme(); // calls B's version of callme r = c; // r refers to a C object r.callme(); // calls C's version of callme }
}

该程序的输出如下:

Inside A’s callme method
Inside B’s callme method
Inside C’s callme method

程序创建了一个名为A的超类以及它的两个子类B和C。子类B和C重载A中定义的callme( )方法。main( )主函数中,声明了A、B和C类的对象。而且,一个A类型的引用r也被声明。

就像输出所显示的,所执行的callme( )版本由调用时引用对象的类型决定。如果它是由引用变量r的类型决定的,你将会看到对A的callme( )方法的三次调用。

熟悉C++的读者会认同Java中的重载方法与C++中的虚函数类似。

开课吧Java课堂之动态方法调度相关推荐

  1. 开课吧Java课堂:StringBuffer全解,非常详细

    StringBuffer是提供了大量的字符串功能的字符串(String)类的对等类.正如你所知,字符串(String)表示了定长,不可变的字符序列.相反,StringBuffer表示了可变长的和可写的 ...

  2. 开课吧Java课堂:字符串如何处理?

    像大多数其他计算机语言一样,Java中的字符串也是一连串的字符.但是与许多其他的计算机语言将字符串作为字符数组处理不同,Java将字符串作为String类型对象来处理. 将字符串作为内置的对象处理允许 ...

  3. 开课吧Java课堂之PrintWriter类的运用

    尽管Java允许用System.out向控制台写数据,但建议仅用在调试程序时或在例题中,对于实际的程序,Java推荐的向控制台写数据的方法是用PrintWriter流.PrintWriter是基于字符 ...

  4. 开课吧Java课堂:如何利用valueOf( )方法实现数据转换

    valueOf( )方法将数据的内部格式转换为可读的形式.它是一种静态方法,对于所有Java内置的类型,在字符串(String)内被重载,以便每一种类型都能被转换成字符串. valueOf( )方法还 ...

  5. 开课吧Java课堂:如何通过接口引用实现接口?

    你可以把变量定义成使用接口的对象引用而不是类的类型.任何实现了所声明接口的类的实例都可以被这样的一个变量引用.当你通过这些引用调用方法时,在实际引用接口的实例的基础上,方法被正确调用.这是接口的最显著 ...

  6. 开课吧Java课堂:什么是ArrayList类

    ArrayList类扩展AbstractList并执行List接口.ArrayList支持可随需要而增长的动态数组.在Java中,标准数组是定长的.在数组创建之后,它们不能被加长或缩短,这也就意味着你 ...

  7. 开课吧Java课堂之如何使用FilenameFilter

    你总是希望能够限制由list( )方法返回的文件数目,使它仅返回那些与一定的文件名方式或者过滤(filter)相匹配的文件.为达到这样的目的,必须使用list( )的第二种形式: String[ ] ...

  8. 开课吧Java课堂:如何使用比较函数?

    下面是一个说明定制的比较函数能力的例子.该例子实现compare( )方法以便它按正常顺序的逆向进行操作.因此,它使得一个树集合按逆向的顺序进行存储. // Use a custom comparat ...

  9. 开课吧Java课堂:是什么是比较函数?

    TreeSet和TreeMap都按排序顺序存储元素.然而,精确定义采用何种"排序顺序"的是比较函数. 通常在默认的情况下,这些类通过使用被Java称之为"自然顺序&quo ...

最新文章

  1. 单片机控制24v电压_最全变频器控制端子接线方法和技巧
  2. 一名优秀的初创企业员工怎么做好工作计划
  3. C/C++预处理宏的总结
  4. 可爱的朋友,你是否有很多问号
  5. 小微型库(1.获取元素的API)
  6. HDU - 1272小希的迷宫
  7. sql中join类型_SQL Join类型概述和教程
  8. 安装罗斯蒙特HART475协议中文版手操器的系统卡和电池
  9. Pyserial文件传输
  10. linux中下载nali + 配置golang环境
  11. 如何将chm格式转换成HTML网页格式
  12. 大学英语B116-2020年12月
  13. 使用R语言画火山图详细步骤
  14. 骑士周游(马踏棋盘)问题
  15. 【网络】Cookie是什么?
  16. Data Science Bowl 2017数据预处理
  17. 苹果全球销量超越小米重回第二,荣耀回归国内手机市场第一梯队
  18. OATS和配对测试应该如何选择? 如何确定正交选择的强度?
  19. u盘安装红旗linux操作系统,制作红旗8的系统安装u盘的方法
  20. error: no such file or directory

热门文章

  1. [转载] python中sort,sorted,reverse,reversed的区别
  2. [转载] Python:numpy中array的用处
  3. [转载] python numpy np.finfo()函数 eps
  4. Python 基础课程第四天
  5. Mysql常用的几种join连接方式
  6. java 基础一 Http请求
  7. [NOIP2003普及组]麦森数(快速幂+高精度)
  8. 阿里云API网关(6)用户指南(开放 API )
  9. 第二阶段--个人冲刺--第七天
  10. 组合数学之排列组合(Permutations and Combinations)(四种情况)