1、java
this關鍵字的四個用法:
(1)this調用本類中的屬性,也就是類中的成員變量。程序員
詳解:引用成員變量post
Public Class Student { String name; // 定義一個成員變量name private void SetName(String name) { // 定義一個參數(局部變量)name this.name=name; // 將局部變量的值傳遞給成員變量 } }
如上面這段代碼中,有一個成員變量name,同時在方法中有一個形式參數,名字也是name,而後在方法中將形式參數name的值傳遞給成員變量name,雖然咱們能夠看明白這個代碼的含義,可是做爲Java編譯器它是怎麼判斷的呢?究竟是將形式參數name的值傳遞給成員變量name,仍是反過來將成員變量name的值傳遞給形式參數name呢?this
答:兩個變量名字若是相同的話,那麼Java如何判斷使用哪一個變量?此時this這個關鍵字就起到做用了。this這個關鍵字其表明的就是對象中的成員變量或者對象中的成員方法。也就是說,若是在某個變量前面加上一個this關鍵字,其指的就是這個對象的成員變量或者對象的成員方法,而不是指成員方法的形式參數或者局部變量!爲此在上面這個代碼中,this.name表明的就是對象中的成員變量,又叫作對象的屬性!然後面的name則是方法的形式參數,代碼this.name=name就是將形式參數的值傳遞給成員變量。這就是上面這個代碼的具體含義。spa
通常狀況下,在Java語言中引用成員變量或者成員方法都是以對象名.成員變量或者對象名.成員方法的形式。不過有些程序員即便在沒有相同變量的時候,也喜歡使用this.成員變量的形式來引用變量,這主要是從便於代碼的閱讀考慮的。一看到這個this關鍵字就知道如今引用的變量是成員變量或者成員方法,而不是局部變量。這無形中就提升了代碼的閱讀性。不過話說回來,這是this關鍵字在Java語言中的最簡單的應用。從這個應用中,咱們能夠看出this關鍵字其表明的就是對象的名字!其實若是是局部變量的話,也是相同的道理。如在上面的代碼中,name不是形式參數,而是一個局部變量。此時Java也會遇到相同的疑惑,即變量名name表明的究竟是局部變量仍是形式參數?name=name到底表明的是什麼含義?根據局部變量的做用域,在方法內部,若是局部變量與成員變量同名的話,那麼是以局部變量爲準。但是在name=name這個賦值語句中,將局部變量的值賦值給本身,顯然並非很合適。根據代碼的含義,原本的意思應該是將局部變量賦值給成員變量。爲了更清晰的表達這個含義,爲此最好採用以下的書寫格式this.name=name。這裏的this關鍵字含義就是對象名student,爲此this.name就表示student.name。翻譯
(2)this調用本類中的成員方法。設計
詳解:code
public class MyServlet1 extends HttpServlet { /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Hello World" + new java.util.Date().toString()); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 通常開發人員習慣把doGet()和doPost()合二爲一 this.doGet(request, response); } }
(3)this調用本類中的其餘方法。orm
詳解:調用類的構造方法server
public class Student { //定義一個類,類的名字爲student。 public Student() { //定義一個方法,名字與類相同故爲構造方法 this(「Hello!」); } public Student(String name) { //定義一個帶形式參數的構造方法 } }
this關鍵字除了能夠調用成員變量以外,還能夠調用構造方法。在一個Java類中,其方法能夠分爲成員方法和構造方法兩種。構造方法是一個與類同名的方法,在Java類中必須存在一個構造方法。若是在代碼中沒有顯示的體現構造方法的話,那麼編譯器在編譯的時候會自動添加一個沒有形式參數的構造方法。這個構造方法跟普通的成員方法仍是有不少不一樣的地方。如構造方法一概是沒有返回值的,並且也不用void關鍵字來講明這個構造方法沒有返回值。而普通的方法能夠有返回值,也能夠沒有返回值,程序員能夠根據本身的須要來定義!不過若是普通的方法沒有返回值的話,那麼必定要在方法定義的時候採用void關鍵字來進行說明。其次構造方法的名字有嚴格的要求,即必須與類的名字相同。也就是說,Java編譯器發現有個方法與類的名字相同才把其看成構造方法來對待。而對於普通方法的話,則要求不可以與類的名字相同,並且多個成員方法不可以採用相同的名字。在一個類中能夠存在多個構造方法,這些構造方法都採用相同的名字,只是形式參數不一樣。Java語言就憑形式參數不一樣來判斷調用那個構造方法。
在上面這段代碼中,定義了兩個構造方法,一個帶參數,另外一個沒有帶參數。構造方法都不會有返回值,不過因爲構造方法的特殊性,爲此沒必要要在構造方法定義時帶上void關鍵字來講明這個問題。在第一個沒有帶參數的構造方法中,使用了this(「Hello!」)這句代碼,這句代碼表示什麼含義呢?
在構造方法中使this關鍵字表示調用類中的構造方法。若是一個類中有多個構造方法,由於其名字都相同,跟類名一致,那麼這個this究竟是調用哪一個構造方法呢?其實,這跟採用其餘方法引用構造方法同樣,都是經過形式參數來調用構造方法的。如上例中,this關鍵字後面加上了一個參數,那麼就表示其引用的是帶參數的構造方法。若是如今有三個構造方法,分別爲不帶參數、帶一個參數、帶兩個參數。那麼Java編譯器會根據所傳遞的參數數量的不一樣,來判斷該調用哪一個構造方法。從上面示例中能夠看出,this關鍵字不只能夠用來引用成員變量,並且還能夠用來引用構造方法。
不過若是要使用這種方式來調用構造方法的話,有一個語法上的限制。通常來講,利用this關鍵字來調用構造方法,只有在無參數構造方法中第一句使用this調用有參數的構造方法。不然的話,翻譯的時候,就會有錯誤信息。這跟引用成員變量不一樣。若是引用成員變量的話,this關鍵字是沒有位置上的限制的。若是不熟悉這個限制的話,那麼仍是老老實實的採用傳統的構造方法調用方式爲好。雖然比較麻煩,可是至少不會出錯。
(4)this調用本類中的其餘構造方法,調用時要放在構造方法的首行。
詳解:返回對象的值
this關鍵字除了能夠引用成員變量或者成員方法以外,還有一個重大的做用就是返回類的引用。如在代碼中,可使用return this,來返回某個類的引用。此時這個this關鍵字就表明類的名稱。如代碼在上面student類中,那麼代碼表明的含義就是return student。可見,這個this關鍵字除了能夠引用成員變量或者成員方法以外,還能夠做爲類的返回值,這纔是this關鍵字最引人注意的地方。
2、
super的使用方法:(表明的是父類的對象)
super.成員變量//super.方法名
super([參數]);調用父類的構造方法
建立對象時(Person person=new Person();//Person person=new Person("張三");),在這兩種狀況下,不管父類有沒有有參數的構造方法,系統都會默認地先調用父類的無參數的構造方法,再調用子類的無參數或有參數的構造方法。
super關鍵和this做用相似,使被屏蔽的成員變量或者成員方法變爲可見,或者說用來引用被屏蔽的成員變量和成員方法。
不過super是用在子類中,目的是訪問直接父類中被屏蔽的成員,注意是直接父類(就是類之上最近的超類)。下面是一個綜合運用super的例子,有兩個類:一個Father類,一個Father類的子類Son,經過這兩個類徹底演示了super的用法,如下是代碼:
package org.leizhimin; public class Father { public String v="Father"; public String x="輸出了Father類的public成員變量x!!!"; public Father() { System.out.println("Father構造方法被調用!"); } public Father(String v){ this.v="Father類的帶參數構造方法!運行了."; } public void outinfo(){ System.out.println("Father的outinfo方法被調用"); } public static void main(String[] args) { // TODO 自動生成方法存根 } } package org.leizhimin; public class Son extends Father{ public String v="Son"; public Son() { super(); //調用超類的構造方法,只能放到第一行。 System.out.println("Son無參數構造方法被調用!"); //super(); //錯誤的,必須放到構造方法體的最前面。 } public Son(String str){ super(str); System.out.println("Son帶參數構造方法被調用!"); } //覆蓋了超類成員方法outinfo() public void outinfo(){ System.out.println("Son的outinfo()方法被調用"); } public void test(){ String v="哈哈哈哈!"; //局部變量v覆蓋了成員變量v和超類變量v System.out.println("------1-----"); System.out.println(v); //輸出局部變量v System.out.println(this.v); //輸出(子類)成員變量v System.out.println(super.v); //輸出超類成員變量v System.out.println("------2-----"); System.out.println(x); //輸出超類成員變量v,子類繼承而來 System.out.println(super.x); //輸出超類成員變量v System.out.println("------3-----"); outinfo(); //調用子類的outinfo()方法 this.outinfo(); //調用子類的outinfo()方法 super.outinfo(); //調用父類的outinfo()方法 } public static void main(String[] args) { new Son().test(); } }
子類Son運行結果:
Father構造方法被調用!
Son無參數構造方法被調用!
------1-----
哈哈哈哈!
Son
Father
------2-----
輸出了Father類的public成員變量x!!!
輸出了Father類的public成員變量x!!!
------3-----
Son的outinfo()方法被調用
Son的outinfo()方法被調用
Father的outinfo方法被調用
說明:此例子僅僅爲了說明super的用法,實際在設計類的時候通常都儘量私有(private)化。
經過上面的例子,下面總結一下super的用法:
第1、從構造方法的角度
在子類構造方法中要調用父類的構造方法,用「super(參數列表)」的方式調用,參數不是必須的。同時還要注意的一點是:「super(參數列表)」這條語句只能用在子類構造方法體中的第一行。
第2、從成員變量的角度
當子類方法中的局部變量或者子類的成員變量與父類的成員變量同名時,也就是子類局部變量覆蓋父類成員變量時,用「super.成員變量名」來引用父類的成員變量。固然,若是父類的成員變量沒有被覆蓋,也能夠用「super.成員變量名」來引用父類的成員變量,不過這是沒必要要的。
第3、從成員方法的角度
當子類的成員方法覆蓋了父類的成員方法時,也就是子類和父類有徹底相同的方法定義(但方法體能夠不一樣),此時,用「super.方法名(參數列表)」的方式訪問父類的方法。