这里需要参数化类型 - 每个树类型都有一系列:状态、观察和动态。
如果我们将观察枚举作为参数类型,我们可以将您的类型转换为如下形式:
public interface Observation<O extends Observation<O>> {
...
}
public interface State<O extends Observation<O>> {
}
public interface Dynamics<O extends Observation<O>> {
getObservationChance(State<O> state, O observation);
}
enum SpecialObservation implements Observation<SpecialObservation> {
FREE, WALL, etc.
}
class SpecialState implements State<SpecialObservation> {
}
class SpecialDynamics implements Dynamics<SpecialObservation> {
getObservationChance(State<SpecialObservation> state, SpecialObservation observation) {
// state should be SpecialState, observation should be SpecialObservation!
}
}
class Main<O extends Observation> {
Main(State<O> state, O observation, Dynamics<O> dynamics) {
dynamics.getObservationChance(state, observation);
}
}
当然,只有当我们的 State 接口的方法对于 getObservationChance 方法足够时,这种方法才有效。
更通用的方法是对所有三种类型进行参数化:
public interface Observation<O extends Observation<O, S, D>,
S extends State<O,S,D>,
D extends Dynamics<O,S,D>>
{
...
}
public interface State<O extends Observation<O,S,D>,
S extends State<O,S,D>,
D extends Dynamics<O,S,D>> {
}
public interface Dynamics<O extends Observation<O,S,D>,
S extends State<O,S,D>,
D extends Dynamics<O,S,D>> {
getObservationChance(S state, O observation);
}
然后我们可以这样定义实现:
enum SpecialObservation implements Observation<SpecialObservation, SpecialState, SpecialDynamics> {
FREE, WALL, etc.
}
class SpecialState implements State<SpecialObservation, SpecialState, SpecialDynamics> {
}
class SpecialDynamics implements Dynamics<SpecialObservation, SpecialState, SpecialDynamics> {
getObservationChance(SpecialObservation state, SpecialObservation observation) {
// state should be SpecialState, observation should be SpecialObservation!
}
}
当然,主类需要所有三个参数:
class Main<O extends Observation<O,S,D>,
S extends State<O,S,D>,
D extends Dynamics<O,S,D>> {
Main(S state, O observation, D dynamics) {
dynamics.getObservationChance(state, observation);
}
}
实际上,在您的情况下,动态仅取决于观察和状态,而不是相反(并且它们彼此不依赖),因此另一种方式是:
public interface Observation {
...
}
public interface State {
}
public interface Dynamics<S extends State,
O extends Observation> {
getObservationChance(S state, O observation);
}
enum SpecialObservation implements Observation {
FREE, WALL, etc.
}
class SpecialState implements State {
}
class SpecialDynamics implements Dynamics<SpecialState, SpecialObservation> {
getObservationChance(SpecialState state, SpecialObservation observation) {
// state should be SpecialState, observation should be SpecialObservation!
}
}
class Main<S extends State, O extends Observation> {
Main(S state, O observation, Dynamics<S, O> dynamics) {
dynamics.getObservationChance(state, observation);
}
}
编辑:
关于 getAllObservations 方法:
只要你能以某种方式使你的类型参数具体化,这里就没有真正的问题。
要访问特定类型的枚举常量列表,您需要访问此类型 - 可以直接访问 (SpecialObservation.values()),也可以使用如下所示的类对象:
class Main<S extends State, O extends Observation> {
public O[] getAllObservations(Class<O> oClass) {
return oClass.getEnumConstants();
}
Main(S state, Dynamics<S, O> dynamics, Class<O> observationClass) {
O[] observations = getAllObservations(observationClass);
for(O o : observations) {
dynamics.getObservationChance(state, observation);
}
}
}
(当然,这只适用于 O 是枚举类的情况。)
如果您有一个混合列表,它会变得更加复杂,并且类型安全地匹配 Dynamics、Action、Observation 和 State 类也不是一件容易的事。