我有类结构
public abstract class AbstractBuilding
实现了一些不相关的内容
这个问题的接口。 public abstract class AbstractAnimalBuilding extends AbstractBuiling
public class AnimalBuildingA extends AbstractAnimalBuilding
public class AnimalBuildingB extends AbstractAnimalBuilding
public class AnimalBuildingC extends AbstractAnimalBuilding
public class AnimalBuildingD extends AbstractAnimalBuilding
在一个完全独立的课程中,我有以下方法:
@FXML
private Button btnAnimalBuildingA;
@FXML
private Button btnAnimalBuildingB;
@FXML
private Button btnAnimalBuildingC;
@FXML
private Button btnAnimalBuildingD;
for (AbstractAnimalBuilding animalBuilding: animalBuildings){
if (animalBuilding instanceof AnimalBuildingA) {
changeButtonDisplay(btnAnimalBuildingA)
} else if (animalBuilding instanceof AnimalBuildingB){
changeButtonDisplay(btnAnimalBuildingB)
} else if (animalBuilding instanceof AnimalBuildingC) {
changeButtonDisplay(btnAnimalBuildingC)
} else if (animalBuilding instanceof AnimalBuildingD){
changeButtonDisplay(btnAnimalBuildingD)
//Do something specific here
}
}
private void changeButtonDisplay(Button buttonToChange){
button.setVisible(true);
}
其中animalBuildings
是包含Set<AbstractAnimalBuilding>
的任意组合的AnimalBuildingX
。
假设需要保留顶部的结构(例如,AnimalBuildingX
HAS 以扩展AbstractAnimalBuilding
),那么什么是比{{1}更好的方法确定if-then-else
是什么类型的建筑物的语句?
如this问题中所述简单地创建一个新的animalBuilding
并且每个Interface
AnimalBuildingX
同时仍在扩展implement
或是否存在我可以使用我目前拥有的结构来做到这一点。
答案 0 :(得分:4)
答案 1 :(得分:3)
这取决于您要代表派生类类型采取的操作。如果必须采取可以在不需要的情况下执行的操作,则调用类知道接口方法的AnimalBuilding
的具体实现是合适的。如果您能找到针对每个具体类(例如getName()
)实现不同的通用方法描述,通常就是这种情况。
如果您需要根据具体类别执行特定操作(例如AnimalBuildingA
与AnimalBuldingB
不同),则可以实施visitor pattern:
public abstract class AbstractAnimalBuilding {
...
public abstract void accept(AnimalBuildingVisitor v);
}
public interface class AnimalBuildingVisitor<T> {
public T visit(AnimalBuildingA a);
public T visit(AnimalBuildingB b);
...
}
accept-method的实现通常是一个班轮
return v.visit(this);
然后,您创建一个Abstract访问器的实现,它执行您想要在循环中执行的工作。然后循环看起来像这样
ConcreteAnimalBuildingVisitor v;
for (AbstractAnimalBuilding animalBuilding: animalBuildings)
animalBuilding.accept(v);
通过这种方式,具体类“识别”自己的具体视角,然后可以执行适当的动作。
答案 2 :(得分:2)
您可以使用泛型保持当前结构并实现您的期望:
首先,我们需要定义一个通用的处理程序接口:
public interface AnimalBuildingHandler<T extends AbstractAnimalBuilding> {
void handle(T type);
}
然后,在您自己的自定义类中,我们可以为每种类型实现特定的功能:
/* Here you can define all */
public void handleAnimalBuildingA(AnimalBuildingA animalBuildingA) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingA);
}
public void handleAnimalBuildingB(AnimalBuildingB animalBuildingB) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingB);
}
然后,我们可以通过将处理程序映射到类型来创建一个实现上述AnimalBuildingHandler接口的魔术处理程序类:
private Map<Class<? extends AbstractAnimalBuilding>, AnimalBuildingHandler<? extends AbstractAnimalBuilding>> handlersMapping;
{ /* default instance initializer */
handlersMapping = new HashMap<>();
handlersMapping.put(AnimalBuildingA.class, new AnimalBuildingHandler<AnimalBuildingA>() {
@Override
public void handle(AnimalBuildingA type) {
handleAnimalBuildingA(type);
}
});
handlersMapping.put(AnimalBuildingB.class, new AnimalBuildingHandler<AnimalBuildingB>() {
@Override
public void handle(AnimalBuildingB type) {
handleAnimalBuildingB(type);
}
});
}
@Override
public void handle(AbstractAnimalBuilding type) {
AnimalBuildingHandler abh = handlersMapping.get(type.getClass());
abh.handle(type);
}
最后,测试方法:
public <T extends AbstractAnimalBuilding> void test() {
List<T> allAnimalBuildings = new ArrayList<>();
allAnimalBuildings.add((T) new AnimalBuildingA());
allAnimalBuildings.add((T) new AnimalBuildingB());
for (AbstractAnimalBuilding aab : allAnimalBuildings) {
handle(aab);
}
}