菜雞的Java課筆記 第十五 this 關鍵字
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描述的物件不同,所以屬性只會儲存在各自的堆記憶體裡面