this 关键字
对于this关键字有三种用法:表示本类属性,调用本类方法,当前对象
this 关键字如何实现属性,方法的调用,以及对象本身的描述
this 首先明确是一个灵活的关键字,他不会明确的表示出任何一个固定的概念
例如:写一个int永远都知道这是一个整型
调用本类属性
类之中有许多的成员,那么在大部分情况下,类里面是直接进行成员的调用
但是很多时候为了能够更加清楚的描述出调用的本类属性,所以调用属性时,可以采用“this.属性”的形式
下面通过一个简短的程序来观察一下this属性的意义
范例:观察有问题的代码
class Person{ private String name; private int age; public Person(String n;int a){ name = n; age = a; } public String getlnfo(){ return "姓名:" +name+ "年龄:" +age; } } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); System.out.println(per.getlnfo()); } }
问题是n 和 a 为什么不能直接是name 和age
这个代码在构造方法上的参数很明确是要做什么,就是为了name和age属性赋值
如果直接是name和age 那么结果就是 名字是null 年龄是0
造成此类原因是在于程序也存在有“就近取用”的原则,以“{}”为界定范围
如果在此范围内存在有指定的变量名称就直接调用,如果没有则会去调用类中的相应的属性
那么当参数与属性名称相同的时候,就会出现混淆的概念,那么就需要用户自己手工的明确指出调用的是属性还是方法中的参数
如是属性则使用“this.属性”进行调用
class Person{ private String name; private int age; public Person(String name;int age){ this.name = name; this.age = age; } public String getlnfo(){ return "姓名:" +this.name+ "年龄:" +this.age; } } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); System.out.println(per.getlnfo()); } }
在以后,类中调用本类属性的时候必须严格按照“this.属性”的形式调用
调用本类方法
利用this 调用方法
在一个类中方法实际上存在有两类:普通方法(this.方法名称(参数)),构造方法(this(参数)),而this调用本类方法的时候两类形式的方法都可以调用
但是语法是不同的
1.调用本类的其他方法:this.方法()
在一个类中可能会存在许多种方法,那么这些方法之间可以直接进行调用
class Person{ private String name; private int age; public Person(String name;int age){ this.name = name; this.age = age; } public String getlnfo(){ this.print(); // 调用本类方法 // print();// 直接调用,但是不标准 return "姓名:" +this.name+ "年龄:" +this.age; } public void print(){ System.out.println("***********"); } } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); System.out.println(per.getlnfo()); } }
2.调用本类其他构造:this()
一个类中是可以存在有构造方法的,而且构造方法可以进行重载,并且构造方法只在实例化对象的时候调用一次
如果说现在有这样一种要求:一个Person类中要求提供有三个构造方法
但是不管调用那种构造方法,都要求执行一行语句“新的Person类对象实例化了”(假设这行语句相当于500行语句)
范例:原始实现形式
class Person{ private String name; private int age; public Person (){ System,out,println("新的Person类对象实例化了(假设这行语句相当于500行语句)"); } public Person(String name){ this.name = name; System,out,println("新的Person类对象实例化了(假设这行语句相当于500行语句)"); } public Person(String name;int age){ this.name = name; this.age = age; System,out,println("新的Person类对象实例化了(假设这行语句相当于500行语句)"); } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); } }
首先程序设计的第一个原则:避免重复代码。按照这个原则来讲,以上的代码实际上并不符合开发要求
那么在这种情况下就可以依靠this()的形式完成调用、
class Person{ private String name; private int age; public Person (){ System,out,println("新的Person类对象实例化了(假设这行语句相当于500行语句)"); } public Person(String name){ this();//调用本类无参构造 this.name = name; } public Person(String name;int age){ this(name); //调用本类无参构造 this.age = age; } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); } }
通过执行可以发现,此时的确已经利用了“this()”实现了类中构造方法的调用执行
但是在整个程序里面实际上对于“this()”的语法是有限制的
该语句只能够放在构造方法的首行
但是在使用“this()”调用本类其他构造方法的时候,应该避免循环的形式出现,留个出口
范例:错误的代码
class Person{ private String name; private int age; public Person (){ this("",10); // 构造方法首行 System,out,println("新的Person类对象实例化了(假设这行语句相当于500行语句)"); } public Person(String name){ this();//调用本类无参构造 this.name = name; } public Person(String name;int age){ this(name); //调用本类无参构造 this.age = age; } public class thisKeyword{ public static void main(String args[]){ Person per = new Person("我",20); } }
为了更方便的理解构造方法互调用的意义所在,下面通过一个具体的实例化来进行说明
开发要求:现在要求定义有一个雇员的信息类,在此类中提供有如下四个属性:姓名,职位,部门,工资
除了四个属性之外还要求提供有四个构造方法:
无参构造:要求姓名为无名氏,职位为待定,部门为后勤部,工资为0.0:
单参构造:(姓名),职位办事员,部门为技术部,工资为700.0;
双参构造:(姓名,职位),部门为工程师,工资为10000.0;
四参构造:
那么下面将针对于此程序给出两种代码的实现形式
第一种实现:传统实现
class Emp{ private String name; 姓名 private String job; 职位: private String dept; 部门: private double sal; 工资 public Emp(){ this.name = "无名氏"; this.job = "待定"; this.dept = "后勤部"; this.sal = 0.0; } public Emp(String name){ this.name = name this.job = "办事员"; this.dept = "技术部"; this.sal = 1700.0; } public Emp(String name,String job){ this.name = name this.job = "工程师"; this.dept = dept; this.sal = 10000.0; } public Emp(String name,String job,String dept,double sal){ this.name = name this.job = job; this.dept = dept; this.sal = sal } public String getlnfo(){ return"姓名:"+this.name+"职位:"+this.job+"部门:"+this.dept+"工资:"+this.sal: } } public class thisKeyword{ public static void main(String args[]){ Emp new = new Emp(); System.out.println(emp.getlnfo); } }
第二种:利用this改进
class Emp{ private String name; 姓名 private String job; 职位: private String dept; 部门: private double sal; 工资 public Emp(){ this("无名氏","待定","后勤部",0.0); } public Emp(String name){ this(name,"办事员","技术部",1700.0); } public Emp(String name,String job){ this(name,"工程师",job,10000.0); } public Emp(String name,String job,String dept,double sal){ this.name = name this.job = job; this.dept = dept; this.sal = sal } public String getlnfo(){ return"姓名:"+this.name+"职位:"+this.job+"部门:"+this.dept+"工资:"+this.sal: } } public class thisKeyword{ public static void main(String args[]){ Emp new = new Emp(); System.out.println(emp.getlnfo); } }
此时已经明显的消除了出现的重复代码,所以这样的设计是比较合理的设计
this 表示当前对象
范例:观察当前对象的概念
class Message{ public void print(){ System.out.println("【Message】this = " + this); // 直接一个this } } public class tthis{ public static void main(String aegs[]){ Message msgA = new Message(); System.out.println("【主类】" + msgA); msgA,print(); System.out.println("************************************"); Message msgB = new Message(); System.out.println("【主类】" + msgB); msgB,print(); } }
那么之前所谓的"this.属性”严格意义上就是当前对象的属性,所以不同的对象调用一个setter方法设置内容的时候,由于this描述的对象不同,所以属性只会保存在各自的堆内存里面