java - 在 Java 中使用子类项列表时如何避免向下转换
问题描述
我有一个抽象类 A 和类 B 和 C。类 B 和 C 扩展 A。我需要将 B 和 C 放在列表中,比如 List。但是,B 和 C 具有独特的方法,因此并非 List 中的所有项目都可以用来调用某些方法,除非我向下转换,这被认为是一种设计味道。
我需要将 B 和 C 保留在同一个列表中,因为我想根据它们的共享属性对它们进行排序。是否将它们保留在其父类型的相同列表中,然后在这种情况下向下转换一个糟糕的设计?
解决方案
我需要将 B 和 C 保留在同一个列表中,因为我想根据它们的共享属性对它们进行排序。
只要要求保持列表以混合类型排序B
,C
都扩展A
an 以调用它们的非继承方法,您别无选择,只能使用List<A>
包含所有类型。
尽管我也尽可能避免向下转换,但这并不意味着在某些情况下它既无用也无必要。
for (A item: sortedList) {
if (item instanceof B) {
Whatever fieldB = ((B) item).getFieldB(); // using non-inherited method of B
} else if (item instanceof C) {
Whatever fieldC = ((C) item).getFieldC(); // using non-inherited method of C
} else {
// either only A or anything different that extends A
}
}
由于JEP 305: Pattern Matching for instanceof从 Java 14 开始,这样的事情变得不那么冗长了:
for (A item: sortedList) {
if (item instanceof B b) {
Whatever fieldB = b.getFieldB(); // using non-inherited method of B
} else if (item instanceof C c) {
Whatever fieldC = c.getFieldC(); // using non-inherited method of C
} else {
// either only A or anything different that extends A
}
}
推荐阅读
- java - 与 Redis 数据库共享 Spring Session
- c# - 无法将单元测试添加到 .NET Core 单元测试项目 VS2017
- python - 插值 Python
- php - 如何将徽标附加到 pdf 文件并发送到邮件
- biztalk - BizTalk 管道组件扩展实用程序包:Zip 管道组件
- r - 使用 tidyverse 转换数据(一列)
- javascript - 在 Vegas 滑块中添加上一个/下一个按钮
- c++ - 如何在 javascript (emscripten) 中覆盖 c++ malloc/free?
- excel - 是否有更简单的方法来检查范围的 Borders.ColorIndex?
- swift - 如何使用 ARKit 从远程服务器加载模型和纹理?