向父类类型化数组列表中添加子类对象。。。

2019-09-10 13:30:39 +08:00
 zhao1014

背景:定义了 Employeee 类 public class Employee { private String name; private double salary; private LocalDate hireDay; //........ Getter and Setter} 定义一个 Manager 类继承 Employee public class Manager extends Employee {

private double bonus;
//........
public void setBouns(double bouns) {
    this.bonus = bouns;
}}

现在创建一个数组列表,ArrayList<employee> staff = new ArrayList<>(); 向列表中添加元素</employee>

staff.add(new Manager("狗蛋",1000,2019,9,10)); 向 staff 中添加 Manager 类是可行的 但是当我想 staff.get(0).setbonus;时却会报错 我想跟这是子类特有属性有关但不知道具体为什么 像是 staff.get(0).getSalary 什么的都是没有问题的 setbonus 却不行这是为什么 而且子类对象可以添加进父类对象的数组列表,我也不清楚为什么,有没有大佬解答?

3547 次点击
所在节点    Java
9 条回复
aguesuka
2019-09-10 13:41:01 +08:00
比如有个 List<Object>,你可以把任意对象放进去,但是取出来的时候还是 Object,必须 cast 成你要的对象
ayonel
2019-09-10 14:21:10 +08:00
取出来,用强制类型转换转成子类对象,即 Manager. 大概这样: (Manager) (staff.get(0)).setbonus;
可以了解下 java 的编译时类型检查和运行时类型检查
cigarzh
2019-09-10 14:38:47 +08:00
编译器报错,你想想啊,staff 里既可以放 Employee 也可以放 Manager,编译器怎么知道你 get()出来的是 Employee 还是 Manager 呢,肯定不能让你 setBonus 啊
zhao1014
2019-09-10 14:42:54 +08:00
@aguesuka 看来我得补充一下有关泛型的知识。。。
zhao1014
2019-09-10 14:43:27 +08:00
@ayonel 感谢!确实需要了解一下
zhao1014
2019-09-10 15:12:32 +08:00
@cigarzh @aguesuka @ayonel
我本来想自己添加一个判断
Manager manager = new Manager("askdj",12312,2342,1,3);//参数为姓名,工资,入职日期的年月日

if (staff.get(3).getClass() == manager.getClass()){
staff.get(3).setbonus(1000);
}//3 是 Manager 类对象的索引值
发现还是报错了。。

而且我开始是这么写的:
Manager manager = staff.get(3)//这里还是报错了,提醒我必须要进行类型转换

正确写法应该是
Manager manager = (Manager)staff.get(3);

我还没有了解泛型的知识,这里应该是 Manger 类添加进 ArrayList<Employee>数组列表时被自动转换成 Employee 类了?
类似于 Employee e = new Manager;这种的向上转型?
zhao1014
2019-09-10 15:43:28 +08:00
@aguesuka @ayonel @cigarzh
看了一下 get ()方法的源码

public E get(int index) {
rangeCheck(index);

return elementData(index);
}


这里是先 rangeCheck 检查索引值是否溢出,溢出的话抛出一个异常
然后 return elementData(index);

我又看了一下 elementData();方法

@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}

这里好像是从 elementData 数组中返回一个对象然后强制类型转换成了 E 类型,也就是我代码中的 Empolyee 类型?
Employee 类型自然是不能调用 setBonus 方法了。。。。
Aresxue
2019-09-11 10:19:08 +08:00
泛型擦除。对于 JVM 来说他只认列表,不关心你列表是啥,统一擦除到上界(对应这里就是子类对象也会被认为是父类对象)
zhao1014
2019-09-11 16:55:09 +08:00
@Aresxue 受教了!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/599608

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX