一:讲解
一个类中有两个对象a、b,一个 function() 方法,怎么才能让a和b都能调用这个方法呢,或者说你怎么才能区分是a还是b调用的这个方法呢?
package haizhu.com;
class Apple{
void function(int i){
i++;
System.out.println(执行function方法结果:" + i);
}
}
public class AppleFunction {
public static void main(String[] args) {
Apple a = new Apple(),
b = new Apple();
a.function(1);
b.function(2);
}
}
为了能够使用简便、面向对象的语法来编写代码——即“发送消息给对象”,编译器做了一些幕后工作。它暗自把“所操作对象的引用”作为第一个参数传递给function(),所以上述两个方法的调用实际上是这样的:
Apple.funciton(a,1);
Apple.funciton(b,2);
那么,this 在哪里呢?我们将上面function()修改一下,将返回值void 改为 Apple,如下所示:
package haizhu.com;
class Apple{
Apple function(int i){
i++;
System.out.println("执行function方法结果:" + i);
return this;
}
void print(){
System.out.println("当前对象的存储地址是:" + this);
}
}
public class AppleFunction {
public static void main(String[] args) {
Apple a = new Apple(),
b = new Apple();
a.function(1).print();
b.function(2).print();
}
}
可以看到a、b两个对象在调用 function() 方法之后接着调用了一个 print() 方法,这是因为function方法中使用“return this”返回了调用这个方法的对象,所以可以用这个返回的对象再次调用 print() 方法。另外,在print()方法中,使用this得到当前对象,并打印出来,结果如下:
执行function方法结果:2
当前对象的存储地址是:haizhu.com.Apple@6af62373
执行function方法结果:3
当前对象的存储地址是:haizhu.com.Apple@459189e1
二:范例
this 关键字使用很多,比如构造器方法中,比如给属性复制的方法中,比如类似上面的一般方法中都有使用:
在构造器中的使用,主要是为了区分 局部变量(name)和 成员变量(this.name)。
package haizhu.com;
class Apple{
//构造器:创建的时候就给对象命名
Apple(String name){
this.name = name;
}
//name属性
private String name;
public String getName(){
return this.name; //在getter方法中使用 this 得到当前对象的name属性值并返回
}
public void setName(String name){ //在setter方法中使用 this 取出当前对象的name属性并赋值
this.name = name;
}
//在方法中使用 this 表示当前对象
int i = 1;
Apple function(){
System.out.println(this.name + "第" + i + "次调用!"); //在一般方法中使用 this 得到当前对象的name属性值
i++;
return this;
}
}
public class AppleFunction {
public static void main(String[] args) {
Apple a = new Apple("A"), //初始化对象的时候命名
b = new Apple("B"); //连续声明两个对象,注意使用的是逗号
for(int x=0;x<3;x++){
a.function();
b.function();
}
}
}
结果:
A第1次调用!
B第1次调用!
A第2次调用!
B第2次调用!
A第3次调用!
B第3次调用!
还可以在使用this关键字调用构造函数方法,但一定要记得 this(),放在第一行。如果有多个构造函数,也可以使用 this(a,b) 传入参数的形式实现重载,根据参数的不同调用不同 的构造函数:
this()构造函数间的调用只能是构造函数调用构造函数,这是为了将某些构造函数私有化,只对外提供一个构造函数的接口。
1、调用无参构造函数
package haizhu.com;
class Apple{
private String variety;
private int weight;
Apple(){
System.out.println("无参构造函数");
}
Apple(String variety){
this.variety = variety;
System.out.println("有参数构造函数 —— variety:"+variety);
}
Apple(String variety,int weight){
this(); //调用无参构造函数
this.variety = variety; //初始化赋值
this.weight = weight; //初始化赋值
}
public void print(){
System.out.println("variety:"+this.variety+"\nweight:"+this.weight);
}
}
public class Text {
public static void main(String args[]){
Apple p = new Apple("红富士",24);
p.print();
}
}
结果:
无参构造函数
variety:红富士
weight:24
2、调用有参构造函数
Apple(String variety,int weight){
this(variety); //调用有参构造函数
this.weight = weight; //只需要给weight赋值就行了,variety在调用的构造函数中赋值
}
结果:
有参数构造函数 —— variety:红富士
variety:红富士
weight:24
三:问题
在上面的方法中有一个问题,a调用 function() 产生的 i 值和b调用 function()产生的 i 值是不共用的,比如,main方法 for() 循环体中改为
for(int x=0;x<3;x++){
a.function().function();
b.function();
}
结果:
A第1次调用!
A第2次调用!
B第1次调用!
A第3次调用!
A第4次调用!
B第2次调用!
A第5次调用!
A第6次调用!
B第3次调用!
这是为什么?i 不是Apple的属性,为什么会不通用?而是a循环的时候接着a上次的值执行i++,而b循环的时候接着b上次的值执行i++?