【踩坑记录】复习泛型知识点时犯的一个错,子类的构造函数不能乱写!

话不多说,直接看源码


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。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章