首页 > 解决方案 > 在 Java 中使用子类项列表时如何避免向下转换

问题描述

我有一个抽象类 A 和类 B 和 C。类 B 和 C 扩展 A。我需要将 B 和 C 放在列表中,比如 List。但是,B 和 C 具有独特的方法,因此并非 List 中的所有项目都可以用来调用某些方法,除非我向下转换,这被认为是一种设计味道。

我需要将 B 和 C 保留在同一个列表中,因为我想根据它们的共享属性对它们进行排序。是否将它们保留在其父类型的相同列表中,然后在这种情况下向下转换一个糟糕的设计?

标签: javagenericsinheritancearraylistdowncast

解决方案


我需要将 B 和 C 保留在同一个列表中,因为我想根据它们的共享属性对它们进行排序。

只要要求保持列表以混合类型排序BC都扩展Aan 以调用它们的非继承方法,您别无选择,只能使用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
    }
}

推荐阅读