2016/4/30

建構式之重載(Overload)與this:Java為例

本篇參考

http://openhome.cc/Gossip/Java/Overload.html

http://openhome.cc/Gossip/Java/This.html

http://programming.im.ncnu.edu.tw/J_Chapter5.htm

視不同情況,有時會有很多個建構式,只要參數型態或個數不同,這稱之為重載(Overload)建構式,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


public class Some {
    private int a = 10;
    private String text = "n.a.";
    public Some(int a) {
        if(a > 0) {
            this.a = a;
        }
    }
    public Some(int a, String text) {
        if(a > 0) {
            this.a = a;
        }
        if(text != null) {
            this.text = text;
        }
    }
    ...}


這時建構式有兩種選擇,一是new Some(100)二是new Some(100, "some text")

有時類似功能的method,提供統一名稱,但傳入的參數型態與個數不同,呼叫的method也不同
public static String valueOf(boolean b)
public static String valueOf(char c)
public static String valueOf(char[] data)
public static String valueOf(char[] data, int offset, int count)
public static String valueOf(double d)
public static String valueOf(float f)
public static String valueOf(int i)
public static String valueOf(long l)
public static String valueOf(Object obj)


1
2
3
4
5
6
7
8
9
10


public class SomeClass {
    public void someMethod() {
    }
    public void someMethod(int i) {
    }
    public void someMethod(float f) {
    }
    public void someMethod(int i, float f) {
    }}


this可用在class的任何地方,在物件建立後為「這個物件」的參考名稱,目前你看到的應用,就是在建構式參數與物件資料成員同名時,可用this加以區別。

1
2
3
4
5
6
7
8
9
10
11


public class CashCard {
    private String number;
    private int balance;
    private int bonus;
    public CashCard(String number, int balance, int bonus) {
        this.number = number;     // 參數number指定給這個物件的number
        this.balance = balance;   // 參數balance指定給這個物件的balance
        this.bonus = bonus;        // 參數bonus指定給這個物件的bonus
    }
    ...}


有種情況,建構式中有的流程是重複的:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


public class Some {
    private int a = 10;
    private String text = "n.a.";
    public Some(int a) {
        if(a > 0) {
            this.a = a;
        }
    }
    public Some(int a, String text) {
        if(a > 0) {
            this.a = a;
        }
        if(text != null) {
            this.text = text;
        }
    }
    ...}


為何重複的東西要一直寫呢?可不可以簡化它?

我們可以這樣寫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


public class Some {
    private int a = 10;
    private String text = "n.a.";
    public Some(int a) {
        if(a > 0) {
            this.a = a;
        }
    }
    public Some(int a, String text) {
       this(a);
        if(text != null) {
            this.text = text;
        }
    }
    ...}


在Java中,this()表呼叫另一建構式,看呼叫this()時給的參數和個數而呼叫哪個建構式,

上例中this(a);呼叫public Some(int a),執行完在做if(text != null)

再看一個範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


package cc.openhome;
class Other {
    { System.out.println("物件初始區塊"); }
    
    Other() {
        System.out.println("Other() 建構式");
    }
    
    Other(int o) {
        this();
        System.out.println("Other(int o) 建構式");
    }}
public class ObjectInitialBlock {
    public static void main(String[] args) {
        new Other(1);
    }}


此範例,會先呼叫Other(int o)版本,到this();再做Other()版本,所以執行結果是:

run:
物件初始區塊
Other() 建構式
Other(int o) 建構式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class People {
    private int age;
    public People(int d) {
        this.age = d;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int d) {
        if (d >= 0 && d <= 130) { // 檢查年齡是否合法
            age = d;
        }
    }
    public void increaseAge() {
        if (age < 130) { // 檢查年齡是否合法
            this.age++;
        }
    }
    public static void main(String[] argv) {
        People e1, e2; // e1,e2 are references to Object People, not the Object themselves
        e1 = new People(3);
        e2 = new People(5);
        e1.setAge(30);
        e2.setAge(50);
        e1.increaseAge();
        e2.increaseAge();
    }
}
this這個keyword表示接收到此訊息的物件。由於設計時是定義Class, 而執行時則是Object接受訊息, Class只有一個, 但Object可以有很多個, 因此必須使用this表達現在接收到此訊息的物件。
它的此訊息應該是指d這個參數,this.age = d;  ,表把現在d這個訊息,指定給age這個(this)物件,而這裡的age就是送給這個class中宣告的變數age這個物件。
我的理解是這樣...

如果要實驗的話也可以,把age換成別的名稱就知道了,我實驗過後,果真這裡的this. ,真是看上面宣告的變數名稱。

有錯歡迎指正

沒有留言:

張貼留言