zoukankan      html  css  js  c++  java
  • this指针与类方法的调用机制

    Java编译器在初始化对象的时候,为同一类型(即同一类)的对象在栈区存储了函数副本(即使对static方法也是如此)。

    为了区别不同对象,新对象生成时,会由编译器生成一个引用变量进行指向。

    该引用变量指向堆区中存储具体对象域属性值的内存区域,即同属一类的对象,共享其类定义的函数。

    既然函数为公用的,那么当同一方法被不同对象调用的时候,如何正确的区别调用此方法的对象以产生正确的行为呢?

    Example:

    class Test

    {

      int num;

      Test(int i)

      {num=i;}

      print()

      { System.out.printl(num);}

    }

    main()

    {

      Test t1=t1(1);

      Test t2=t2(2);

      t1.print();

          t2.print();

     }

    Test类具有两个对象 t1、t2,此处它们都调用了print()方法,根据print方法的定义,它们需要打印出自己的属性num的数值。

    那么print方法是如何被调用,以保证被指向正确的内存空间的呢?我们调用函数的时候并没有显示的给出对象引用作为参数啊!

    实质是:我们在通过对象调用方法的时候,编译器暗自的把“所操作对象的引用”作为第一个参数传递给了print。

    e: t1.print();  ----->      Test.Print(t1);//此处仅作为理解,并无实际意义

    这样一来,方法就能准确的的根据编译器传递来的对象引用确定操作的对象,从而避免了出错。

    e: print()----->print(){System.out.print(this.number)}//此处的this关键字(C++中称this指针)代表了执行该方法的对象。

    this关键字并不常用,但遇到要将调用的对象作为范围值返回的情况,this还是很重要的。

    Example:

    class Dog

    {

      String name;

      Dog(String dogname){dogname=name};

      Dog bark()

     {

      System.out.printl(name+"is barking");

          return this;

      }

    }

    mian()

    {

      Dog dog=new Dog("Happy");

         dog.bark().bark().bark();

    }

    调用bark()方法后,通过this指针返回调用对象本身,从而可以实现对bark()方法的无限调用!

    在java中除静态方法外,其余的方法调用一定要与其调用对象联系在一起。

    同一个类中,方法和域的操作都无需指明调用对象, 但是在一个类中调用另一个类得方法(静态方法、导出类调用基类方法除外),一定要指明调用对象。

    值得一提的是static方法,static方法不能操作除static对象的域成员(static成员不能算是对象的域成员),static方法不需要this指针,故其不需要对象支持!

    static方法一般提供一些全局的基本操作(在C++中称为全局方法),但是在Java中不允许脱离类而单独的存在方法,故将其放在类中做全局方法。

    由于static方法,不能访问对象的域成员,故一般其需要的参数由调用的时候全部给出。

    如 :

    Package MathMethod

    Class MathAdd

    {

      static double add(ball b1, ball b2){ return b1.diameter+b2.diameter ;}

    }

    此方法中就将计算两个球的总直径长度作为了一个静态方法,并将两个球的对象的引用作为参数传入。

    (这是非常重要的,非static方法是隐式传递this指针,而static中必须显示给出对象引用,可以据此灵活编写静态方法)

    由于static方法需要依附于任何对象进行调用,鼓起调用格式可以直接为   类名.static方法名。

    java中的包机制,给予了其一种更为方便的调用方法,允许像C++中的全局方法一样方便的对其进行调用。

    Example:  上例中add方法的包路径为:  MathMethod.MathAdd.add;

    由于add是静态方法,我们在别的包内可以直接调用它,只需要静态import 包。

    e: Package Ballcal

    import static MathMethod.MathAdd.*;

    class Ball

    {

         double diameter;

         Ball(float dia){diameter= dia};

         addBall(Ball two)

        {

       add(this, two);

         }

    }

    由于使用了import static添加包,可以实现对add方法的直接访问。(注意添加包的路径,一定是该方法根目录以上的目录)

  • 相关阅读:
    《JavaScript高级程序设计》笔记:客户端检测(九)
    《JavaScript高级程序设计》笔记:BOM(八)
    《JavaScript高级程序设计》笔记:函数表达式(七)
    《JavaScript高级程序设计》笔记:面向对象的程序设计(六)
    小tips:JS的Truthy和Falsy(真值与假值)
    footer固定在页面底部的实现方法总结
    WEB前端需要了解的XML相关基础知识
    vuex最简单、最直白、最全的入门文档
    原生JS替代jQuery的各种方法汇总
    数据挖掘优秀工具对比
  • 原文地址:https://www.cnblogs.com/airwindow/p/2553142.html
Copyright © 2011-2022 走看看