1. 程式人生 > >Java中this,super關鍵字

Java中this,super關鍵字

一.this

  Java關鍵字this只能用於方法方法體內。當一個物件建立後,Java虛擬機器(JVM)就會給這個物件分配一個引用自身的指標,這個指標的名字就是this。因此,this只能在類中的非靜態方法中使用,靜態方法和靜態的程式碼塊中絕對不能出現this,這在“Java關鍵字static、final使用總結”一文中給出了明確解釋。並且this只和特定的物件關聯,而不和類關聯,同一個類的不同物件有不同的this。下面給出一個使用this的綜合例項,以便說明問題:

package org.zzl; public class Test6 {  private int number;
 private String username;
 private String password;
 private int x = 100;
 public Test6(int n) {
  number = n;  // 這個還可以寫為: this.number=n;
 }
 public Test6(int i, String username, String password) {
  // 成員變數和引數同名,成員變數被遮蔽,用"this.成員變數"的方式訪問成員變數.
  this.username = username;
  this.password = password;
 }
 // 預設不帶引數的構造方法
 public Test6() {
  this(0, "未知", "空"); // 通過this呼叫另一個構造方法
 }
 public Test6(String name) {
  this(1, name, "空"); // 通過this呼叫另一個構造方法
 }
 public static void main(String args[]) {
  Test6 t1 = new Test6();
  Test6 t2 = new Test6("遊客");
  t1.outinfo(t1);
  t2.outinfo(t2);
 }
 private void outinfo(Test6 t) {
  System.out.println("-----------");
  System.out.println(t.number);
  System.out.println(t.username);
  System.out.println(t.password);
  f(); // 這個可以寫為: this.f();
 }
 private void f() {
  // 區域性變數與成員變數同名,成員變數被遮蔽,用"this.成員變數"的方式訪問成員變數.
  int x;
  x = this.x++;
  System.out.println(x);
  System.out.println(this.x);
 }
 
 //返回當前例項的引用
 private Test6 getSelf() {
  return this; 
 }
}
  執行結果如下:
-----------
0
未知

100
101
-----------
0
遊客

100
101
          看著上面的例子,說明在什麼情況下需要用到this
        第一、通過this呼叫另一個構造方法,用發是this(引數列表),這個僅僅在類的構造方法中,別的地方不能這麼用。
        第二、函式引數或者函式中的區域性變數和成員變數同名的情況下,成員變數被遮蔽,此時要訪問成員變數則需要用“this.成員變數名”的方式來引用成員變數。當然,在沒有同名的情況下,可以直接用成員變數的名字,而不用this,用了也不為錯,呵呵。
        第三、在函式中,需要引用該函所屬類的當前物件時候,直接用this。
        其實這些用法總結都是從對“this是指向物件本身的一個指標”這句話的更深入的理解而來的,死記不然容易忘記而且容易搞錯,要理解!   二、super           super關鍵和this作用類似,是被遮蔽的成員變數或者成員方法或變為可見,或者說用來引用被遮蔽的成員變數和成員成員方法。
不過super是用在子類中,目的是訪問直接父類中被遮蔽的成員,注意是直接父類(就是類之上最近的超類)。下面是一個綜合運用super的例子,有兩個類:一個Father類,一個Father類的子類Son,通過這兩個類完全演示了super的用法,一下是程式碼:
  package org.zzl; 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.zzl; 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); //輸出超類成員變數x
  
  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的用法:
        第一、在子類構造方法中要呼叫父類的構造方法,用“super(引數列表)”的方式呼叫,引數不是必須的。同時還要注意的一點是:“super(引數列表)”這條語句只能用在子類構造方法體中的第一行。
        第二、當子類方法中的區域性變數或者子類的成員變數與父類成員變數同名時,也就是子類區域性變數覆蓋父類成員變數時,用“super.成員變數名”來引用父類成員變數。當然,如果父類的成員變數沒有被覆蓋,也可以用“super.成員變數名”來引用父類成員變數,不過這是不必要的。
        第三、當子類的成員方法覆蓋了父類的成員方法時,也就是子類和父類有完全相同的方法定義(但方法體可以不同),此時,用“super.方法名(引數列表)”的方式訪問父類的方法。
          this、super的用法也不過這些,只有理解了其中的原理,才不會跌入陷阱!