深入理解this关键字在面向对象设计中的应用
2015-03-16 22:17
435 查看
</pre><p></p><p>最近,在补习笔试题的时候,遇到一种有趣的现象,供大家思考一下:</p><p></p><pre name="code" class="java">public class Dervied extends Base { private String name = "dervied"; public Dervied() { tellName(); printName(); } public void tellName() { System.out.println("Dervied tell name: " + name); } public void printName() { System.out.println("Dervied print name: " + name); } public static void main(String[] args){ new Dervied(); } } class Base { private String name = "base"; public Base() { tellName(); printName(); } public void tellName() { System.out.println("Base tell name: " + name); } public void printName() { System.out.println("Base print name: " + name); } }
运行结果
Dervied tell name: null
Dervied print name: null
Dervied tell name: dervied
Dervied print name: dervied
为什么在基类的构造函数中,使用this对象调用tellName
、printName都是子类的方法?
在调用java方法创建栈帧的时候,jvm会通过this秘密的传递一个当前实例。所以,当我们在执行Dervied
的构造函数的时候,默认会调用父类Base
的构造函数,在调用父类B构造函数的时候,秘密的传进去的当前实例是 Dervied
的实例----因为是在Dervied
的构造函数中调用的Base,所以,这个地方的this反而代表了Dervied
。
上面的结论有没有那本书对这个有详细的描述呢?《java编程思想》里面,对这块是这样描述的:
讨论主题:当生成子类对象时,先初始化父类的构造函数,在父类构造函数中,this关键字调用子类的方法,表示子类的对象,为什么呢?
一、Java 中This的用法
this的作用?
使用this区分成员变量和局部变量;当类中有两个同名变量,一个属于类(类的成员变量),而另一个属于某个特定的方法(方法中的局部变量)。
使用this表示当前调用方法的对象引用;
假设你希望在方法的内部获得对当前对象的引用,可使用关键字this。this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用。见示例3。
Button bn; … bn.addActionListener(this);
使用this调用本类中另外一个构造函数。this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。 见示例5。
Point(int a,int b){ x=a; y=b; } Point(){ this(1,1); //调用point(1,1),必须是第一条语句。 }
<span style="background-color: rgb(255, 255, 255); color: rgb(44, 44, 44); font-family: 宋体;font-size:18px; text-indent: 28px;">this使用注意点:</span>
this()在同一类内调用其它方法。
this()指的是对象,所以,调用非静态成员函数,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
尽管可以用this调用一个构造器,但却不能调用两个。
this()需放在构造方法内第一行。
从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。
二、C++中This的用法
C++中,有如下说法:<span style="font-size:18px;">基类构造函数中的this指针 首先,构造函数的实质是,在一个确定的地址上,构造对象。 构造函数语法上,没有返回值,语义上是有的,返回被构造者本身。 所以,父类子对象构造时,子类对象,虽然没有开始,调用子类构造函数的内部的代码,子类对象本身的地址是已经确定的,而子类的布局是由子类类型的定义,而不是单独某个函数确定的。 这样父类子对象,相对子类对象的偏移量,也是确定的,单一非虚拟继承偏移量为0; 这样两个对象是重叠的,所以地址也相同 于是在某个子类对象的构造过程中, 父类构造函数的 this指针,和子类构造函数的 this指针,也是指向同一地址的,只是类型不同。 注意 this 是指向对象的,是非静态成员函数才会有的,不是对象才有的。 换句话说 是 对象语法调用函数才有的。</span>
// class A{ public: A ():x(0){}; int x; }; A a; // 调用 A() 实质是 a.A(); this == &a ; // A a ; // 已经为 a 分配内存了,然后才会自动调用构造函数。 // 在分配的内存上构造对象。 a.Hello();//Hello 的 this ==&a; A *p = &a;// p->Hello(); //this ==p; A *p = new A(); // 先分配内存,p = operator new(sizeof(A)); // 然后构造对象 *p;执行A() 实质是 p->A(); // this == p;
PS:
编译程序,按照子类的布局,自动调整 this指针 调用父类的构造函数。
三、结论:
总而言之,C++和java中,this 指针是类的不是对象拥有的,但是对象可以提供它的地址,作为 this 指针,来调用非静态成员函数。
本文作者水平有限,如有不对的地方,还请各位朋友指点出来。另外,本人是一个普通的java程序员,正在升入学习this指针,本文引用了很多经典的资料,让我涨了不少姿势。这里谢谢一下文章的作者。
四、参考资料
[1]Thinking in Java 3rd[2] this super 在java里使用时应注意的地方
http://hengdao325200.blog.163.com/blog/static/340522006626114027/
[3] Java 类体中的this、super的正确用法
[4]http://xiaocao000.spaces.live.com/Blog/cns!F[/url]826A925CF33491A!126.entry
[5]http://my.oschina.net/kalo/blog/333202
相关文章推荐
- PHP面向对象深入理解之四(设计模式-单例模式)
- PHP面向对象深入理解之四(设计模式-观察者模式)
- PHP面向对象深入理解之四(设计模式-工厂模式)
- “键”无虚发(——谈数据库在面向对象设计中键的应用)(下)
- 深入理解Android组件间通信机制对面向对象特性的影响详解
- 深入理解Java对象的序列化与反序列化的应用
- [.net 面向对象程序设计深入](3)UML——在Visual Studio 2013/2015中设计UML活动图
- 面向对象设计原则和创建SOLID应用的5个方法
- JS面向对象应用二(多差异流程的WEB客户端逻辑设计实现)
- Java面向对象 Main函数 静态的应用 单例设计模式
- 面向对象设计(一)——对象和类的理解
- 深入理解C++面向对象机制(一)多继承
- [.net 面向对象程序设计深入](2)UML——在Visual Studio 2013/2015中设计UML用例图
- 面向对象复习,深入理解static关键字
- php面向对象深入理解(一)
- 面向对象设计学习之路——CRC卡及其应用
- 面向对象设计原则理解
- PHP面向对象之旅:深入理解static变量与方法
- PHP面向对象之旅:深入理解static变量与方法
- 面向对象程序设计(OOP设计模式)-行为型模式之观察者模式的应用与实现