课时9:this调用本类属性
摘要:本次分享的主题是 This 调用本类属性。主要分为一个部分:
使用 This 关键字表示或调用当前对象的属性
继续来探讨 Java 中一个较为棘手的概念,即名为 This 的关键字。有同学表示这次的内容较为复杂。首先要强调的是 This 可以算是Java 中较为复杂的一个关键字。这是因为 This 的使用形式决定了它的高度灵活性。
在这个程序中使用 This 关键字可以实现以下三个方面的描述。第一个称之为当前类中的属性,紧接着列出这四个属性。第二个是当前类中的方法,这里提到的方法可能包括普通方法与构造方法。使用 This 加括号调用构造方法,而使用 This 加方法名称加括号就是调用普通方法,这一点很好理解。
之后还有一个环节,把它称之为使用 This 来描述当前对象。这是一个相对灵活的概念,要讲透彻需要一些时间。从整体上看 This 最令人困惑的部分也在于此。
使用 This 关键字表示或调用当前对象的属性
下面来看一下这究竟是怎么回事。首先来看第一个概念:使用 This关键字来表示或调用当前对象的属性。
那么在讨论 This 之前,先来看一个问题。通过目前的分析可以发现利用构造方法或者是 Setter 方法都可以为对象的属性赋值,但是在进行赋值时之前可能采用的是如下的定义形式。
这个代码是这样写的。首先定义一个名为 Person 的类,在这个类中定义了两个属性:一个是 Private String Name ,另一个是Private Int Age 。通常会为这些属性提供 Setter 和 Getter 方法,但在这里为了简化省略了这些方法的具体实现。
class Person { private String name ; private int age ; // sett } public class JavaDemo { //主类 public static void main(String args[]){ } }
之后通常会编写一个构造方法,接受 String 类型的 Name 和 Int类型的 Age 作为参数。在构造方法的实现中会将传入的 Name 赋值给类的 Name 属性,将传入的 Age 赋值给类的 Age 属性。接着可能会添加一个名为 Tell 的方法,该方法简单地输出姓名和年龄。这里只是一个简单的代码示例, Tell 方法中会输出“姓名:”加上 Name 属性的值,以及“年龄:”加上 Age 属性的值。
现在编写如下代码:创建一个 Person 类的实例 pr ,使用 New 关键字和 Person 构造方法,传入“王五”作为姓名, 38 作为年龄。然后调用 Pr 的 Tell 方法。代码编写完成后,很简单,也很容易理解。现在将这段 Java 代码保存为 JavaDemo.java 文件,并通过Java 编译器执行它,运行后发现没有问题,程序能够正常运行并输出结果。
而这是一个再正常不过的简单程序。相信大家一看就能轻松理解。然而有人可能会提出疑问说:“老师,我对这段话有点费解。”
class Person { private String name ; private int age ; public Person(String n,int a) { name = n ; age = a ; } public void tell() { System.out.println("姓名:"+ name + "、年龄:"+ age); } // setter、getter略 } public class JavaDemo { //主类 public static void main(String args[]) { Person per = new Person("王五",38) ; per.tell() ;| }
但是在构造方法的定义过程中发现了一个小问题。问题出在哪里呢?出在参数的名称上。具体来说构造方法中的两个参数是为了给类的 Name 和 Age 绘制属性初始化。然而此时使用的参数名称,比如 N 和 A 并不直观。
最好的做法应该如何实现呢?你的目标不就是为了给变量 Name 和 Age 赋值吗?如果直接使用 Name 作为参数名,相比使用 N 和 A ,前者显然更为合适且直观,而我的想法是将传入的 Name 参数值赋给对象的 name 属性,但这里似乎有些混淆,那么该如何明确指定每个参数对应哪个属性呢?
按照当前的代码方式编写后,编译和执行都没有问题,但执行结果却是空的。也就是说现在代码中存在问题,只是编译时未能发现。如果尝试在构造方法中将参数名称修改为 Name 和 Age ,就会发现无法正确地为对象的属性设置值。在这个过程中由于参数名和属性名之间的混淆,导致属性无法被正确设置。
class Person { private string name ; private int age ; public Person (String n,int a) { name = n; age = a ; } public void tell() { System.out.println("姓名:"+ name + "、年龄:"+ age); } // setter、getter略 } public class JavaDemo {//主类 public static void main(String args[]){ Person per = new Person("王五",38) ; per.tell() ; } }
D:\mldnjava>javac JavaDemo.java D:\mldnjava>java JavaDemo 姓名:王五、年龄:38 D:\mldnjava>
那么为什么会出现这样的一种情况呢?首先大家一定要明确一件事情:在 Java 程序中,大括号是作为结构体的边界符号,那么在程序中,当使用变量时——无论是参数还是属性,都统称为变量,并且都会以大括号作为查找边界。
public Person(String name,int age){ name = name; age= age ; }
什么叫查找边界呢?以当前例子来讲,假设现在要写字,比如写一句“老婆你很帅”。当我要拿笔来写时,如果桌上就有笔,显然就不会跑到十万八千里外去找林强借一根笔,那样可能到那里都已经老了。这是不现实的事情。
既然桌上有笔就会直接用桌上的笔来写字。现在回到这个问题上来。在构造方法中你有没有 Name 这个参数?有没有 Age 这个参数?构造方法里既有 Name 又有 Age ,那么这个时候还会去查找构造方法外面的 Name 和 Age 吗?
以边界为例,这个地方有没有 Name 和 Age 的参数名称呢?如果有,那么还需要到构造方法外面去找这个参数吗?不需要,只需要遵循“就近取用”的原则。所以同学们,按照“就近取用”的原则,构造方法中的参数并不会直接访问到类中的属性。
为了明确区分构造方法中的参数和类中的属性,通常会在引用类中的属性时,在属性名前加上一个关键字 This 。所以明白这个含义了吗? This 关键字就是用来表示当前对象的属性,即“本位属性”。
class Person{ private String name; private int age; public Person(String name,int age) { name = name ; age= age ; } public void tell() { System.out.println("姓名:" + name + "、年龄:"+ age); } // setter、getter略 } public class JavaDemo { // 主类 public static void main(String args[]) { Person per = new Person("王五",38) ; per.tell() ; } }
所以正确的代码形式应该怎么写呢?应该在构造方法中使用 This 关键字来明确区分参数和属性,比如 This.name = Name ;和 This.H = H 。这样写之后再次编译和执行程序代码,应该就能正常地为属性赋值了。这就是 This 关键字的用法。
因此要告诉大家的是在以后编写代码时,当你需要引用属性时,请确认一下它是不是属性。如果是属性那么就要在属性名前加上 This 来进行访问。
这里想告诉大家一件事情,在以后的程序开发过程中请牢记这句话:在你所编写的程序代码中,只要是访问类中的属性,特别是明确指代本类中的属性时,请一定要加上 This 关键字来实现访问。你们明白这句话的意思吗?也就是说从此以后,你们要养成一个习惯,只要访问类中的属性,就在属性名前加上 This 。
这个习惯真的很重要,因为很多人在这个地方吃过亏。我最早写代码的时候,就因为有一次忘了加 This ,结果出了错,并且查了好久都没找到问题所在。那个数值就是不对劲,检查了所有地方都没问题,最后才发现就是少了个 This 。
所以你们以后一定要养成这个习惯,只要是访问类中的属性,就用 This 关键字来明确访问。这样做可以确保你的代码更加清晰、准确,避免不必要的错误。
private String name ; private int age ; public Person(String name,int age) { this.name = name ; this.age= age ; } public void tell() { System.out.println("姓名:" + this.name + "、年龄:"+this.age) ; } //setter、getter 略 }