繼承了什麼?


你正在設計一個遊戲,裏頭有劍士:
public class SwordsMan {
    private String name;
    private int level;
    private int blood;

    public String getName() {
return name; }
    public void setName(String name) { this.name = name; }
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    public int getBlood() { return blood; }
    public void setBlood(int blood) { this.blood = blood; }

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

也有魔法師:
public class Magician {
    private String name;
    private int level;
    private int blood;

    public String getName() {
return name; }
    public void setName(String name) { this.name = name; }
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    public int getBlood() { return blood; }
    public void setBlood(int blood) { this.blood = blood; }

    public void fight() {

        System.out.println("攻擊魔法");
    }
    public void cure() {
        System.out.println("治療魔法");
    }
}

顯然地,裏頭有許多程式碼重複了,考慮劍士與魔法師都是一種角色(Sprite),你可以設計一個父類別Sprite:
public class Sprite {
    private String name;
    private int level;
    private int blood;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    public int getBlood() { return blood; }
    public void setBlood(int blood) { this.blood = blood; }
}

然後讓劍士繼承角色:
public class SwordsMan extends Sprite {
    public void fight() {
        System.out.println("揮劍");
    }
}

魔法師也繼承角色:
public class Magician extends Sprite {
    public void fight() {
        System.out.println("攻擊魔法");
    }
    public void cure() {
        System.out.println("治療魔法");
    }
}

這麼一來,重複的程式碼了可以在父類別中維護,不過你發現,還有個fight()方法雖然本體內容定義不同,但方法簽署確實重複定義了,這方法簽署定義應該放到父類別,於是你可以改這麼撰寫
Sprite
public class Sprite {
    private String name;
    private int level;
    private int blood;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    public int getBlood() { return blood; }
    public void setBlood(int blood) { this.blood = blood; }

    public void fight() {
    }
}

fight()什麼都不作,本體為空,只是為了定義方法簽署,這樣好像怪怪的,即然不定義本體,那不如定義為抽象方法吧!這樣可以不寫那奇怪的空本體:
public abstract class Sprite {
    private String name;
    private int level;
    private int blood;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
    public int getBlood() { return blood; }
    public void setBlood(int blood) { this.blood = blood; }

    public abstract void fight();
}

因為類別有抽象方法,所以類別本身亦要為抽象類別,這麼一來,除了不用寫那空本體之外,子類別也就一定得
重新定義fight()方法,還不用擔心打成了fi9ht()

以上是繼承的最基本應用,那麼想想,你繼承了什麼?父類別的程式碼定義?只對了一部份!

SwordsMan與Magician不僅繼承了Sprite中的程式碼定義,其實,還繼承了是一種的關係,劍士是一種角色,魔法師也是一種角色,也就是說,繼承不單只是繼承父類別的程式定義,還繼承了種類

請繼續看 這是哪種東西?