我有一个所有其他子类都可以扩展的基类PlanItem。
一个Objective扩展了PlanItem。
策略扩展了PlanItem。
战术扩展了PlanItem。
任务扩展了PlanItem。
收获:
目标具有策略对象列表。将其称为子项列表。
策略包含策略子列表。
战术有一个子任务列表。
我本可以逐字制作4个完全克隆的类,但这会使编辑变得很痛苦。我选择使用继承,但是随之而来的是循环依赖的问题。
目前我是:
让基本PlanItem类具有一个字段:
private ObservableList<? extends PlanItem> childPlanItems = FXCollections
.observableArrayList();
我有一个带控制器的FXML,ViewPlanItemController,它在TableView中显示特定项目的统计信息和子列表。
public class ViewChildItemsController<E extends PlanItem> {}
该TableView具有添加,编辑,查看和删除子项的选项。
如果我想查看一个子项,那么我们用控制器递归地加载另一个ViewPlanItem.fxml。问题是,每次我想加载另一个ViewChildItem.fxml时,都需要为其提供子类型,以便它可以查看它们。
如果要查看目标,则可以初始化控制器,以便它知道显示策略类型的项目。
如果需要,这是控制器的init方法:
/**
* Initializes the values of the items to be displayed.
*
* @param list The list of child items to display.
* @param defCtor Default ctor of each child item.
* @param copyCtor Copy ctor of each child item.
*/
public void initValues(ObservableList<E> list, Supplier<E> defCtor, UnaryOperator<E> copyCtor) {
childItemsTableView.setItems(list);
statisticsPanelController.init(list);
this.defCtor = defCtor;
this.copyCtor = copyCtor;
}
我该怎么做?如果我位于ViewPlanItemController类本身之内,我如何知道子项的类类型?从目标->策略->策略->任务来看,需要进行一些类级别的递归。
最佳答案
由于Task
实例没有(不应)具有子项,因此将子项列表放入其超类之一是没有意义的。最好将它放在另一个类中,也许:
abstract class ParentPlanItem <E extends PlanItem> extends PlanItem {
// Moved here from PlanItem:
private ObservableList<E> childPlanItems = FXCollections.observableArrayList();
// You might also need these:
private Supplier<E> childConstructor;
private unaryOperator<E> childCopyConstructor;
}
那可以是
Objective
,Strategy
和Tactic
的超类。它具有足够的信息来正确调用控制器的init方法。在何处获得childConstructor
和childCopyConstructor
的值是一个单独的问题。我可能会考虑使它们成为相关类的最终静态字段,但是各个类的构造函数仍然需要设置它们。大概。您可能会变得更聪明。