我已经阅读了这篇文章http://www.javapractices.com/topic/TopicAction.do?Id=31,其中说使用instanceof预先检查我的对象是不好的做法。
但是在这种情况下我不知道怎么做:我有一个返回项目列表的API。此项列表返回用户和管理员
如果我投射了一个像(用户)项目的项目,一旦它命中一个Admin,我就会有一个ClassCastException
for(Item item : items){
if (item instanceof User){
((User)item).getName());
((User)item).getEmail());
}
else if (item instanceof Admin){
((Admin)item).getName());
((Admin)item).getEmailList().getPrimary());
}
}
由于它是一个API,我无法修改Item,Item上没有子方法,而且电子邮件检索方法也不同。我还有其他选择吗?
答案 0 :(得分:5)
使用所有常用方法定义一个接口,让User和Admin类实现该接口,并在这些情况下仅使用该接口来访问对象。
编辑(因为您无法更改API)
备选方案是:
坚持您当前的解决方案。这似乎是最好的交易。
定义一个接口,创建两个实现此接口的包装类并包装原始对象。从OOP的角度来看,这更加干净,但我认为在你的情况下这有点过分,但这实际上取决于。
理论(!):您也可以使用反射,但不要这样做 - 它会使代码更糟糕 - 特别是当只有两个不同的编译时已知项目子类型
答案 1 :(得分:2)
理想情况下,您可以将接口更改为Item,以便它显示方法,以便在您的代码中处理用户或管理员时无关紧要 - 以便Item定义getName()和getEmail()用户和管理员酌情实施这些方法。
但是,由于您不控制您正在使用的API,因此您别无选择,只能按现在的方式编写代码。
因此,引用文章提出的观点很好,但它假设您可以更改您正在使用的类。
答案 2 :(得分:-1)
首先,您的代码没有任何效果。您正在调用getter而没有任何赋值,因此您实际上不使用getter的返回值。
其次,使用不同类型的元素进行集合是一种不好的做法。在你的ccase用户和管理员。
第三,如果你甚至需要这样的收藏,你可以使用其他模式来执行你需要的。例如,访客模式看起来像是一个很好的替代方法。