【发布时间】:2017-04-05 20:39:48
【问题描述】:
想象以下类:
public abstract class State {}
public abstract class View : MonoBehaviour {
public State state;
}
现在我想从这两个类中派生出StateA 和ItemA。
public class StateA { // some properties }
public class ViewA : View {
public StateA state;
}
ViewA 应该只接受 StateA 作为其状态。设置一个假设的StateB 应该是不可能的。当我试图设置ViewA的状态时
View view = someGameObject.GetComponent<View>;
view.state = new StateA ();
只会设置基类的状态。在我的情况下,转换为 ViewA 是不可能的,因为它必须动态转换。
现在我想出了两个可能的解决方案。
解决方案 1 - 类型检查和强制转换
所有状态类保持不变。基类正在检查状态的正确类型。
public abstract class View : MonoBehaviour {
public State state;
public Type stateType;
public void SetState (State state) {
if (state.GetType () == this.stateType) {
this.state = state;
}
}
}
要访问ViewA 中的状态,我这样做:
(StateA)this.state
解决方案 2 - 统一方式
State 将更改为从 MonoBehaviour 派生。
public abstract class State : MonoBehaviour {}
要为项目添加状态,我只需向游戏对象添加一个新的StateA 组件。然后该项目使用 GetComponent 加载该状态以访问它。
viewA.gameObject.AddComponent<StateA> (); // set state with fixed type
viewA.gameObject.AddComponent (type); // set state dynamically
this.gameObject.GetComponent<StateA> (); // get state in item class
结论
在我看来,这两种解决方案都不理想。你们知道做这种事情的更好方法吗?我希望你明白我想要达到的目标。期待看到您的想法。
编辑
似乎我的问题过于简单化了。为了弄清楚我为什么这样做,可以在 UI 中将Item 视为View。 StateA 没有任何功能。相反,它只是让视图知道它应该做什么的一些属性。例如,对于表格视图,状态将包含要显示的内容的集合。
public class StateA : State {
SomeObject[] tableViewData; // which data to load into the table view
}
或者换个角度看。
public class StateB : State {
bool hideButtonXY; //should I hide that button?
}
在另一堂课中,我保留了上次显示视图及其各自状态的历史记录。通过这种方式,我正在从普通的网络浏览器实现一个来回功能。 我希望这能说明我的意图。
【问题讨论】:
-
在
Item中使用State实例时,是否需要知道具体的子类? -
(如...是什么阻止您让
ItemA存储State类型的变量,而不是专门存储StateA?) -
将特定实现耦合在一起通常不是一个好主意,您能否在示例中说明为什么需要这样做?
-
我更新了问题以明确我想要实现的目标。
标签: c# inheritance unity3d properties polymorphism