2016/5/1

OOP:繼承(Inheritance) 以Java為例

本篇參考  http://openhome.cc/Gossip/Java/Inheritance.html

繼承的目的就是為了避免多個類別重複相同的實作。

先假設今天要開發一個RPG遊戲,一開始角色有劍士和魔法師,先定義劍士:


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
29
30


public class SwordsMan {
    private String name;   // 角色名稱
    private int level;     // 角色等級
    private int blood;     // 角色血量

    public void fight() {
        System.out.println("揮劍攻擊");
    }

    public int getBlood() {
        return blood;
    }
    public void setBlood(int blood) {
        this.blood = blood;
    }

    public int getLevel() {
        return level;
    }
    public void setLevel(int level) {
        this.level = level;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }}


再來是魔法師:

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
29
30
31
32
33
34


public class Magician {
    private String name;   // 角色名稱
    private int level;     // 角色等級
    private int blood;     // 角色血量
    
    public void fight() {
        System.out.println("魔法攻擊");
    }
    
    public void cure() {
        System.out.println("魔法治療");
    }

    public int getBlood() {
        return blood;
    }
    public void setBlood(int blood) {
        this.blood = blood;
    }

    public int getLevel() {
        return level;
    }
    public void setLevel(int level) {
        this.level = level;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }}


可看到上面粗體+斜體+底線的地方與劍士重複了?重複的東西幹嘛一直寫呢?所以繼承就出現了


現在開始實作繼承(Inheritance)

步驟一:把重複的地方"拿出"去,當父類別,並且給父類一個新名字

步驟二:把子類別繼承父類別

現在來開始做

步驟一:把重複的地方"拿出"去,當父類別,並且給父類一個新名字叫Role


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
29
30


package Cast;
public class Role {
    private String name;
    private int level;
    private int blood;
    
    public int getBlood() {
        return blood;
    }

    public void setBlood(int blood) {
        this.blood = blood;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }}


步驟二:把子類別繼承父類別

1
2
3
4
5
6


package Cast;
public class SwordsMan extends Role {
    public void fight() {
        System.out.println("揮劍攻擊");
    }}


關鍵字extends繼承,把SwordsMan類別繼承Role類別,前面是子類別繼承父類別

Magician也一樣繼承Role:


1
2
3
4
5
6
7
8
9
10


package Cast;
public class Magician extends Role{
    public void fight() {
        System.out.println("魔法攻擊");
    }
    
    public void cure() {
        System.out.println("魔法治療");
    }}


如此一來,Role中定義的程式碼,SwordsMan與Magician中都有了

 如何確定有真的繼承?試試看知:

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


package rpg;
import Cast.Magician;
import Cast.SwordsMan;
public class RPG {
    public static void main(String[] args) {
       demoSwordsMan();
       demoMagician();
    }
    static void demoSwordsMan() {
        SwordsMan swordsMan = new SwordsMan();
        swordsMan.setName("Justin");
        swordsMan.setLevel(1);
        swordsMan.setBlood(200);
        System.out.printf("劍士:(%s, %d, %d)%n", swordsMan.getName(), 
                swordsMan.getLevel(), swordsMan.getBlood());
    }
    static void demoMagician() {
        Magician magician = new Magician();
        magician.setName("Monica");
        magician.setLevel(1);
        magician.setBlood(100);
        System.out.printf("魔法師:(%s, %d, %d)%n", magician.getName(), 
                magician.getLevel(), magician.getBlood());
    }}


注意,如果demoMagician與demoSwordsMan method沒有加static會編譯錯誤,因為main是static宣告,只有static能用static還有final宣告的類別不能被繼承,否則會編譯錯誤!

換句話說,如果你不想你的類別被其他子類別繼承,那就請你把類別宣告成final
final class classname{
         //...
}

還有,Java中,子類別只能繼承一個父類別,所以基本上你不會看到這種東西:
package Cast;
public class Magician extends Role,Role2,...{
    .............................
}


問題1:private成員可繼承嗎?可以

問題2:private成員繼承後,子類別可存取它嗎?不能,除非父類別提供method給子存取

反白看答案

沒有留言:

張貼留言