将一个方法调用同一个方法主体关联起来,就是绑定。 绑定分两种 :前期绑定 和 后期绑定 。

绑定-------------

| -----前期绑定-------编译期绑定 { static , final 方法 (private 方法属于final 方法);数据成员;}

|

|------后期绑定-------运行时绑定 { 普通的成员方法 ;}

总结:对于方法来说, 除了static 和final 方法外, 其他的方法都是后期绑定。

编译时对引用只检查被声明的类型,而不看实际类型。

将某个方法声明为 final 的作用-------

{  防止该方法被覆盖,即告诉编译器,对此方法不需要动态绑定;}

多态产生的问题:

引用《java编程思想》(第四版)里的例子:

  1. class Glyph{
  2. void draw(){print("Glyph.draw();")}
  3. Glyph(){
  4. print("Glyph() before draw()");
  5. draw();
  6. print("Glyph() after draw()");
  7. }
  8. }
  9.  
  10. class RoundGlyph extends Glyph{
  11. private int radius = 1;
  12. RoundGlyph(int r){
  13. radius = r;
  14. print("RoundGlyph.RoundGlyph(), radius = " + radius);
  15. }
  16. void draw(){
  17. print("RoundGlyph.draw(), radius = "+ radius);
  18. }
  19. }
  20.  
  21. public class PolyConstructors{
  22. public static void main(String[] args){
  23. new RoundGlyph(5);
  24. }
  25. }
  26.  
  27. /*Output:
  28. Glyph() before draw()
  29. RoundGlyph.draw(), radius = 0
  30. Glyph() after draw()
  31. RoundGlyph.RoundGlyph(), radius = 5
  32. */

new 一个RoundGlyph 对象时,构造器的执行顺序 是: 父类 ----->子类, 所以, 先执行Glyph 的构造器,

然后执行 RoundGlyph 的构造器,但是,Glyph 的构造器调用了 draw 成员函数,所以该执行 Glyph 的draw 成

员函数? No,因为多态,对于一般成员函数来说, 运行时才绑定, 因为new 的是 RoundGlyph 对象, 所以

绑定的是RoundGlyph 的draw 函数,与此同时,RoundGlyph 的 成员radius 还没初始化,所以出现了 0 。

接下来,就轮到 RoundGlyph 的构造函数了,因为在构造函数里 ,RoundGlyph 的成员 radius 先初始化了,

然后执行 RoundGlyph 的draw 函数,所以,radius = 5。

总结: 尽量避免在构造器中调用其他方法,防止因多态产生一些意想不到的问题。

现在,我们来看看C++ 中会不会出现这样的问题,把java 代码改成C++:

  1. #include<iostream>
  2. using namespace std;
  3.  
  4. class Glyph
  5. {
  6. public:
  7. Glyph(){
  8. cout<<"Glyph() before draw() \n";
  9. draw();
  10. cout<<"Glyph() after draw() \n";
  11. }
  12. void draw(){
  13. cout<<"Glyph.draw(); \n";}
  14. };
  15.  
  16. class RoundGlyph: public Glyph
  17. {
  18. public:
  19. RoundGlyph(int r){
  20. radius = r;
  21. cout<<"RoundGlyph.RoundGlyph(), radius = "<< radius<<'\n';
  22. }
  23. void draw(){
  24. cout<<"RoundGlyph.draw(), radius = "<<radius<<'\n';
  25. }
  26. private:
  27. int radius ;
  28.  
  29. };
  30. int main(){
  31. RoundGlyph * r = new RoundGlyph(5);
  32. return 0;
  33. }

运行结果为:

没有出现同样的问题,可以看出C++ 在多态的这个问题上表现得比较好。学 java 有一个作用,那就是让你

更好地理解 C++ 。

版权声明:本文为博主原创文章,未经博主允许不得转载。

java 方法调用绑定--《java编程思想》学习笔记的更多相关文章

  1. Java编程思想 学习笔记8

    八.多态  在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征. 多态通过分离做什么和怎么做,从另一角度将接口和实现分离开来. “封装”通过合并特征和行为来创建新的数据类型.“实现 ...

  2. Java编程思想 学习笔记5

    五.初始化与清理 1.用构造器确保初始化  在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化.创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造 ...

  3. [Java编程思想-学习笔记]第3章 操作符

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  4. Java编程思想学习笔记——类型信息

    前言 运行时类型信息(RTTI:Runtime Type Information)使得我们可以在程序运行时发现和使用类型信息. Java在运行时识别对象和类的信息的方式: (1)一种是RTTI,它假定 ...

  5. java 方法调用绑定

    将一个方法调用同一个方法主体关联起来被称作绑定.若在程序执行前进行绑定(由编译器和连接器实现),叫做前期绑定.读者可能从来没有听说过这个术语,因为它在面向过程语言中不需要选择就默认的绑定方式.例如C语 ...

  6. Java编程思想 学习笔记12

    十二.通过异常处理错误  Java的基本理念是“结构不佳的代码不能运行”. Java中的异常处理的目的在于通过使用少于目前数量的代码来简化大型.可靠的程序的生成,并且通过这种方式可以使你更加自信:你的 ...

  7. Java方法调用的字节码指令学习

    Java1.8环境下,我们在编写程序时会进行各种方法调用,虚拟机在执行这些调用的时候会用到不同的字节码指令,共有如下五种: invokespecial:调用私有实例方法: invokestatic:调 ...

  8. Java编程思想学习笔记_6(并发)

    一.从任务中产生返回值,Callable接口的使用 Callable是一种具有泛型类型参数的泛型,它的类型参数表示的是从方法call返回的值,而且必须使Executor.submit来去调用它.sub ...

  9. Java编程思想学习笔记_2(继承和多态)

    静态初始化: 静态初始化只在必要的时刻进行.(即当程序需要加载类进入内存的时候,执行静态初始化.静态变量和静态代码块的初始化顺序,按照在代码中声明的顺序老执行.例如:如果要执行某个public类,那么 ...

随机推荐

  1. [020] Android模拟器访问本地Web应用

    本篇文章试图解决这样一个问题:如何在Android模拟器上访问本地的Web应用? 例如,在你的开发机器上启动一个Tomcat服务,接着打开电脑上的浏览器,默认情况下输入http://localhost ...

  2. 如何解决:ERROR: the user data image is used by another emulator. aborting 的问题

    问题概述: 在启动Android模拟器时出现以下错误,导致启动失败. ERROR: the user data image is used by another emulator. aborting. ...

  3. for,foreach,iterator的用法和区别

    for,foreach,iterator的用法和区别 相同点:   三个都可以用来遍历数组和集合不同点:1.形式差别 for的形式是for(int i=0;i<arr.size();i++){. ...

  4. HDU 2544 最短路 (最短路,spfa)

    题意:中文题目 思路:spfa+SLF优化.关于SPFA的详情请戳我 #include <bits/stdc++.h> using namespace std; , INF=0x7f7f7 ...

  5. [Everyday Mathematics]20150109

    设 $A$ 是 $n$ 阶复方阵, 其特征多项式为 $$\bex f(\lm)=(\lm-\lm_1)^{n_1}\cdots(x-\lm_s)^{n_s}, \eex$$ 其中 $\lm_i$ 互不 ...

  6. Unable to execute dex: method ID not in [0, 0xffff]: 65536

    http://ingramchen.io/blog/2014/09/prevention-of-android-dex-64k-method-size-limit.html

  7. memcache 分布式,算法实现

    memcached 虽然称为 “ 分布式 ” 缓存服务器,但服务器端并没有 “ 分布式 ” 功能.每个服务器都是完全独立和隔离的服务. memcached 的分布式,则是完全由客户端程序库实现的. 这 ...

  8. window下版本控制工具Git 客户端安装

    安装使用 1.下载msysgit http://code.google.com/p/msysgit/ 2.下载tortoisegit客户端安装 http://code.google.com/p/tor ...

  9. golang学习遭遇duang...duang...duang

    初学golang时,在windows上使用liteIDE进行,很多语法都能自己调整. 后来使用linux桌面,再次编写时,发现很多东西都忘掉了.这难道就是习惯gocode后的弊端吗?还是人到 前中年 ...

  10. setFocusable、setEnabled、setClickable区别

    setClickable  设置为true时,表明控件可以点击,如果为false,就不能点击:“点击”适用于鼠标.键盘按键.遥控器等:注意,setOnClickListener方法会默认把控件的set ...