Java:无需强制转换即可获取子类的属性

Java:无需强制转换即可获取子类的属性,java,attributes,subclass,visitor,Java,Attributes,Subclass,Visitor,假设我有一个超类Order和两个子类VehicleOrder和TaskOrder。两者都从超类中继承了许多方法,但都有一个特定字段:VehicleOrder有一个模型和TaskOrder有一个任务 现在,在另一个类中,我有一个顺序列表。在该方法中,我需要根据订单的特定字段进行计算 我现在的解决方案是使用两个方法“污染”超类Order,它们分别是getModel()和getTask(),默认情况下返回null,并且可以被子类覆盖。然后,另一个类检查null,如果不是null,则进行计算。但这感觉不

假设我有一个超类
Order
和两个子类
VehicleOrder
TaskOrder
。两者都从超类中继承了许多方法,但都有一个特定字段:
VehicleOrder
有一个
模型
TaskOrder
有一个任务

现在,在另一个类中,我有一个顺序列表。在该方法中,我需要根据订单的特定字段进行计算

我现在的解决方案是使用两个方法“污染”超类
Order
,它们分别是
getModel()
getTask()
,默认情况下返回null,并且可以被子类覆盖。然后,另一个类检查null,如果不是null,则进行计算。但这感觉不是正确的方法

因为我不知道另一个类中的常规订单列表的子类类型,所以我无法强制转换以获取该属性

解决此问题的唯一其他方法是使用
访问者模式
,但这感觉有点过头了。。是吗


有一种干净的方法可以做到这一点吗?

为什么不在基类上添加一个抽象方法
doccalculation
,然后在子类中重写它呢。当您在订单列表上迭代时,只需调用
doccalculation
方法并相应地进行处理。

提取出任务和模型都可以实现的公共基类(或接口)。让订单引用该类型,而不是每个订单类型引用具体类型

这可能说起来容易做起来难,这取决于任务和模型的相似性/差异。它可能需要重构和抽象更多的东西来工作


如果这被证明是太多的更改/工作,回到访问者模式。

访问者是一个合理的解决方案。也可以将计算转移到VehicleOrder和TaskOrder上。您可能还希望保留两个单独的列表,而不是一个列表()。污染超类是功能性的,但脆弱且不受欢迎。从您的其他评论来看,
Visitor
似乎是一个很好的解决方案。好吧,多亏了两者。我曾考虑保留两个单独的列表,但为此,我需要使用Visitor将
Order
-对象添加到正确的列表中,这样我就不会有任何收获。移动计算不起作用,因为不同的计算需要计算类的不同部分。因为计算需要计算类中的不同列表/变量,取决于特定字段是模型还是任务。。。为了能够覆盖,计算应该使用相同的字段,因此字段可以作为参数传递,对吗?