话不多说,直接看源码
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);
}