您的位置:首页 > 其它

深入理解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。

讨论主题:当生成子类对象时,先初始化父类的构造函数,在父类构造函数中,this关键字调用子类的方法,表示子类的对象,为什么呢?

一、Java 中This的用法


什么是this?定义: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: