2011年3月10日 星期四

漫談物件導向(七) - this與super

this與super

super關鍵字表示父類別的意思,程式中可以使用super叫用父類別中被子類別覆蓋的變數或方法。下列程式碼中第9行super.showme()表示叫用父類別PARENT中的print()方法。

1.    public class PARENT {
2.        protected void showinfo() {
3.            System.out.println("invoke the method of class PARENT.");
4.        }
5.    }
6.    public class CHILD extends PARENT {
7.        public void showinfo() {
8.            System.out.println("invoke the method of class CHILD.");
9.            super.showinfo(); // 叫用父類別的showme()方法
10.      }
11.      public static void main(String[] args) {
12.          CHILD objDemo = new CHILD();
13.          objDemo.showinfo();
14.      }
15. }

this則代表物件本身,當你想取得對當前物件參照,可使用this關鍵字。下列程式碼第4行this.name = name,第一個name所代表的是DEMO類別中的資料成員,而等號後面的name則是代表setName()方法中的引數名稱。

1.    public class DEMO {
2.        private String name;
3.        public setName(String name) {
4.            this.name = name; //前一個name是DEMO的資料成員; //後一個name是setName()方法的引數
5.        }
6.    }

再者,super/this與super()/this()二者混淆了。super()表示叫用父類別的預設建構子(沒有引數的建構子),this()則是表示叫用自身類別的預設建構子。

還有一點要注意,當Java建立子類別物件時,JVM會先呼叫父類別的預設建構子,之後才繼續執行子類別建構子的程式碼,換言之,在建構子程式碼的第一行隱含了super()敘述。

以下列程式碼為例,類別B繼承類別A,當程式碼第11行執行建構類別B物件實體時,就會進入類別B的建構子 (程式碼第7行),由於存在著繼承關係,JVM先呼叫執行類別A的建構子 (程式碼第2~4行),之後再繼續類別B的建構子程式 (程式碼第8~9行),因此程式執行結果會輸出"AB"。

1.    class A{
2.        public A(){
3.            System.out.print("A");
4.        }
5.    }
6.    class B extends A {
7.        public B(){ // 會先隱含執行super()敘述
8.            System.out.print("B");
9.        }
10.      public static void main(String[] args) {
11.          new B();
12.      }
13.  }

對上述程式碼而言,類別B建構子程式碼相當於:

1.    public B (){
2.        super ();
3.        System.out.print ("B");
4.    }

super()/this()也可加入引數,表示叫用有引數的建構子。最後要強調的是super()或this()均需放在方法的第一行,還有this和super指的都是物件,所以,不可以在static環境中使用,包括static方法及static區塊。