【踩坑記錄】複習泛型知識點時犯的一個錯,子類的構造函數不能亂寫!

話不多說,直接看源碼


Hero.java

public class Hero {
    public String name;
    public float hp;
    public int damage;
    public Hero() {
    }
    // 增加一個初始化name的構造方法
    public Hero(String name) {
        this.name = name;
    }
    // 重寫toString方法
    public String toString() {
        return name;
    }
}

APHero.java

public class APHero extends Hero {
    public String name;
    public float hp;
    public int damage;
    public APHero() {
    }
    // 增加一個初始化name的構造方法
    public APHero(String name) {
        this.name = name;
    }
    // 重寫toString方法
    public String toString() {
        return name;
    }
    public void magicAttack() {
        System.out.println("進行魔法攻擊");
    }
}

TestCollection.java

public class TestCollection {
    public static void main(String[] args) {
        ArrayList<Hero> hs = new ArrayList<>();
        ArrayList<APHero> aphs = new ArrayList<>();
        hs.add(new Hero("nomarl Hero"));
        aphs.add(new APHero("AP Hero"));
        iterate(hs);
        iterate(aphs);

    }
    public static void iterate(ArrayList<? extends Hero> list){
        for (Hero hero : list){
            System.out.println(hero.name);
        }
    }
}

我們的運行結果是這樣的:

在這裏插入圖片描述爲什麼APHero的name是null呢?

如果在Hero,APHero類中都定義有變量name,則在執行
for (Hero hero : list) { System.out.println( hero.name ); }
這裏的時候,會輸出hero的name,對於Hero類是沒問題的
但是對於APHero,他的構造函數得到的name是APHero裏對應的name
轉換爲父類Hero後,它們的name還是原來的name,所以 hero.name就會爲null。

解決方法:

(一)將構造函數裏的
    public APHero(String name) {
        this.name = name;
    }
換成:
    public APHero(String name) {
        super(name);
    }
這樣構造函數用的是父類的構造函數,所以還是父類Hero對應的name;

(二)將APHero裏定義的name去掉,使它們直接繼承父類Hero的name。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章