this关键字如何实现属性、方法的调用,以及对象本身的描述。
this是一个灵活的关键字,没有明确的表示任何固定概念。
利用this调用本类属性
为了显示调用的是本类属性,调用时采用“this.属性”的方式。
范例:观察问题代码
class Persons{
private String name;
private int age;
public Persons(String name,int age){
name=name;
age=age;
}
public String getInfo(){
return "姓名:"+name+",年龄:"+age;
}
}
public class StringDemo {
public static void main(String args[]){
Persons per = new Persons("张三",20);
System.out.println(per.getInfo());
}
}
造成此类问题的原因在于程序也存在“就近取用”的原则。以“{}”为界定范围,如果在此范围中存在有指定变量名称就直接调用,如果没有,则会去调用类中的相应属性。
当参数和属性名称相同的时候,就会出现混淆的概念,需要用户
自己手工指出调用的是属性还是方法中的参数。如果是属性,则使用“this.属性”调用。
class Persons{
private String name;
private int age;
public Persons(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
return "姓名:"+this.name+",年龄:"+this.age;
}
}
public class StringDemo {
public static void main(String args[]){
Persons per = new Persons("张三",20);
System.out.println(per.getInfo());
}
}
在以后类中调用本类属性的时候必须严格按照“this.属性”的形式调用。
利用this调用方法
一个类中一般有两类方法:普通方法和构造方法。this都可以调用,但语法不同。
1 调用本类的其他方法。this.方法()。
类间的多个方法可以互相调用。
class Persons{
private String name;
private int age;
public Persons(String name,int age){
this.name=name;
this.age=age;
}
public String getInfo(){
this.print();//调用本类方法,不写this结果相同
return "姓名:"+this.name+",年龄:"+this.age;
}
public void print(){
System.out.println("************");
}
}
public class StringDemo {
public static void main(String args[]){
Persons per = new Persons("张三",20);
System.out.println(per.getInfo());
}
}
2 调用本类其他构造:this()。
一个类中是可以存在构造方法的,构造方法可以重载,并且构造方法只在实例化对象的时候调用一次。Person类中有三个构造方法,不管调用哪个构造方法,都输出一句“新的Person类对象实例化了”(假设这行语句相当于50行代码)
范例:原始实现方式
class Persons{
private String name;
private int age;
public Persons(){
System.out.println("【相当于50行代码】新的Person类对象实例化了。");
}
public Persons(String name){
this.name=name;
System.out.println("【相当于50行代码】新的Person类对象实例化了。");
}
public Persons(String name,int age){
this.name=name;
this.age=age;
System.out.println("【相当于50行代码】新的Person类对象实例化了。");
}
}
public class StringDemo {
public static void main(String args[]){
Persons per = new Persons("张三",20);
}
}
首先程序设计的第一原则:避免重复代码。按照此原则,以上代码并不符合开发要求,此时可以依靠this()的形式完成调用。
class Person{
private String name;
private int age;
public Person(){
System.out.println("【相当于50行代码】新的Person类对象实例化了。");
}
public Person(String name){
this();//调用本类无参构造
this.name=name;
}
public Person(String name,int age){
this(name);//调用本类单参构造
this.name=name;
this.age=age;
}
}
public class Hello {
public static void main(String args[]){
Person per = new Person("张三",20);
}
}
可以实现类中构造方法的调用执行,但是“this()”的语法是有限制的:该语句是能放在构造方法的首行。
但是在使用“this()”调用本类其他构造方法时应避免循环形式出现,留个出口。循环调用嘛。递归构造器调用是不被允许的。
为了方便理解构造方法互调用的意义所在,下面通过一个具体的实例说明。
开发要求:要求定义一个雇员信息类
属性:姓名、职位、部门、工资;
构造方法:
- 无参构造:姓名为无名氏、职位为待定、部门为后勤部、工资为0.0;
- 单参构造(姓名):职位为办事员、部门为技术部、工资为700.0;
- 双参构造(姓名、部门):职位为工程师、工资为3000.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=700.0;
}
public Emp(String name,String dept,double sal){
this.name=name;
this.dept=dept;
this.job="工程师";
this.sal=3000.0;
}
public Emp(String name,String job,String dept,double dal){
this.name=name;
this.job=job;
this.dept=dept;
this.sal=sal;
}
public String getInfo(){
return "姓名:"+this.name+",职位:"+this.job+",部门:"+this.dept+",工资:"+this.sal;
}
}
public class StringDemo {
public static void main(String args[]){
Emp emp = new Emp();
System.out.println(emp.getInfo());
}
}
第二种:利用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,"办事员","后勤部",700.0);
}
public Emp(String name,String dept,double sal){
this(name,dept,"工程师",3000.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 getInfo(){
return "姓名:"+this.name+",职位:"+this.job+",部门:"+this.dept+",工资:"+this.sal;
}
}
public class StringDemo {
public static void main(String args[]){
Emp emp = new Emp();
System.out.println(emp.getInfo());
}
}
消除重复代码,设计比较合理。
this表示当前对象
为了区分当前正在操作类种方法的对象,可以用this表述。
范例:观察程序
class Person{
}
public class Hello {
public static void main(String args[]){
Person perA = new Person();
System.out.println("Hello类中的对象输出:"+perA);
System.out.println("-------------------");
Person perB = new Person();
System.out.println("Hello类中的对象输出:"+perB);
}
}
因为使用了关键字new,一定会开辟新的堆内存空间,所以对象的编码是不可能一样的。
范例:观察this
class Person{
public void print(){
System.out.println("Person类的输出,this="+this);
}
}
public class Hello {
public static void main(String args[]){
Person perA = new Person();
System.out.println("Hello类中的对象输出:"+perA);
perA.print();
System.out.println("-------------------");
Person perB = new Person();
System.out.println("Hello类中的对象输出:"+perB);
perB.print();
}
}
如果现在是由perA对象调用print()方法的时候,this=perA;
如果现在是由perA对象调用print()方法的时候,this=perA;
可以发现this的对象引用是会随着调用类方法对象的不同而有所不同,属于一个相对性的概念。
this.属性:当前对象的属性。
范例:观察一个思考题
class A{
public A(){//2 执行A类的无参构造函数
B b= new B(this);//3 实例化B类对象
//此时this出现在A类,所以为A类的当前对象
//此方法是由x对象实例化的时候调用的,所以this=x;
b.get();//6 调用B类中的get()方法
}
public void print(){//8 输出信息
System.out.println("Hello World!");
}
}
class B{
private A a;
public B(A a){//4 a=x
this.a=a;//5 a对象与x对象指向同一块堆内存
}
public void get(){
this.a.print();//7 a=x,x.print()(a.print())
}
}
public class Hello {
public static void main(String args[]){
A x=new A();//1 实例化A类对象为x,此时调用A的构造方法
}
}
不要求掌握
总结
以后开发中就使用“this.属性”、“this.方法”、“this()”。