- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
想象以下类:
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
结论
在我看来,这两种解决方案都不理想。你们知道做这种事情的更好方法吗?我希望你明白我想要达到的目标。期待看到您的想法。
编辑
看来我把问题简单化了。为了弄清楚为什么我这样做,请将 Item
视为 UI 中的 View
。 StateA
没有任何功能。相反,它只是一些让 View 知道它应该做什么的属性。例如,对于 TableView ,状态将包含要显示的事物的集合。
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?
}
在另一个类中,我保留了最后显示的 View 及其各自状态的历史记录。通过这种方式,我可以从普通网络浏览器实现来回功能。我希望这能表明我的意图。
最佳答案
这是一个相当普遍的问题,由需要在 Unity 中使用 MonoBehaviours 的奇怪方式和常见的继承误用共同引起。这不是您可以解决的问题,而是您为了避免而设计的问题。
这完全取决于您为什么需要 State 的子类,但我假设它类似于:基本 State 具有一些基本逻辑,而派生的 StateA 具有一些新的/修改的属性/逻辑。假设这是真的:
代码示例:
abstract class State {
public int sharedField;
public sealed void DoThing() {
sharedField = 1;
DoThingInternal();
}
protected abstract void DoThingInternal();
}
abstract class Item {
State state;
public abstract void TestMethod();
}
class StateA : State {
public int customField = 10;
protected override void DoThingInternal() {
sharedField = 10;
}
}
class ItemA : Item {
public ItemA() {
//read from somewhere else, pass it in, etc.
state = new StateA();
}
public override void TestMethod() {
state.DoThing();
Console.WriteLine(state.sharedField); //will print 10
}
}
这是一种非常常见的模式,尤其是在 Unity 中,当您想像这样使用继承时。这种模式在 Unity 之外也能很好地工作,并且避免泛型,因此通常了解它很有用。
注意: public 方法中 sealed 属性的作用是防止其他人/你自己以后试图隐藏它(public new void DoThing() 或只是 public void DoThing())然后在它不起作用时感到困惑。
如果您要覆盖它,那么因为您通过 base 类调用它,它会调用该函数的 base 版本而不是您的新方法。将它定义为抽象/虚拟并由基类本身调用可以解决这个问题。这确实意味着您已经有效地定义了:
interface IState {
public int sharedField;
public void DoThing();
}
因此您可能会看到,使用接口(interface)并注意实现也可以实现相同的结果。
编辑使示例符合问题:
abstract class State {
public sealed Button[] GetHiddenButtons() {
GetHiddenButtonsInternal();
}
public sealed object[] GetObjects() {
GetObjectsInternal();
}
protected abstract Button[] GetHiddenButtonsInternal();
protected abstract object[] GetObjects();
}
abstract class Item {
State state;
public abstract void Render();
}
class StateA : State {
public Button[] _hiddenButtons;
public object[] _objects;
public StateA()
{
//get hidden buttons from somewhere/pass them in/create them.
_hiddenButtons = new Button[0];
//get objects from somewhere/pass them in/create them.
_objects = new object[0];
}
protected override Button[] GetHiddenButtons() {
return _hiddenButtons;
}
protected override object[] GetObjects() {
return _objects;
}
}
class ItemA : Item {
public ItemA() {
//read from somewhere else, pass it in, etc.
state = new StateA();
}
public override void Render() {
//get objects
var objects = state.GetObjects(); //returns array from StateA
//get hidden buttons to hide
var hiddenButtons = state.GetHiddenButtons();
}
}
基本上,您正在做的是创建一个足够通用的界面,以满足您需要状态执行的任何操作。该模式没有规定您需要如何返回它们,因此您的 GetHiddenButtons() 方法可以:返回 ID 列表、返回对象、联系游戏对象以获取列表、返回硬编码列表等。
此模式允许您完全按照自己的意愿行事,您只需确保基本状态的设计足够通用,以允许您这样做。
关于c# - 将基类属性覆盖为派生类型并通过基类访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43241213/
我知道 C++ 中的 overriding 是什么。但是,是否存在覆盖?如果有,是什么意思? 谢谢。 最佳答案 在 C++ 术语中,您有 覆盖(与类层次结构中的虚拟方法相关)和 重载(与具有相同名称但
我想捕获位于另一个元素下的元素的鼠标事件。 这是我所拥有的示例:http://jsfiddle.net/KVLkp/13/ 现在我想要的是当鼠标悬停在红色方 block 上时蓝色方 block 有黄色
以下报道 here我尝试创建一个带有重叠散点图的箱线图。 但是当我运行时: In [27]: table1.t_in[table1.duration==6] Out[27]: counter 7
有一个 JS Fiddle here , 你能在不克隆到新对象的情况下替换 e.target 吗? 下面重复了那个 fiddle 的听众; one.addEventListener('click',
首先要解决重复的可能性: 我不是询问 Override 是什么、它的含义或 @Override 在 java 文档注释之外。那是我不是问 /**Some JavaDoc Comment*/ @over
我想要高于定义的数组。它存储点及其坐标。 public static List simpleGraph(List nodes) { int numEdges = nodes.size() *
我在 http://olisan.dk/blog/ 有一个博客- 如您所见,有一个 28 像素的高间隙(边距顶部)...在 style.css 中: margin-top: 0; 也被设置为 marg
Vulkan 句柄是指向 struct 的不透明指针,或者只是无符号的 64 位整数,具体取决于 VK_USE_64_BIT_PTR_DEFINES 的值: #if (VK_USE_64_BI
我正在尝试提供一个行为类似于 DataGridTextColumn 的 DataGrid 列,但在编辑模式下有一个附加按钮。我查看了 DataGridTemplateColumn,但似乎更容易将 Da
使用 Django 1.10 我想在用户名中允许\字符,因为我在使用“django.contrib.auth.middleware.RemoteUserMiddleware”的 Windows 环境中
我正在尝试使用 ffmpeg 将 Logo 放入 rtmp 流中。我的 ffmpeg 版本是 ffmpeg version 4.3.1目前在我的复杂过滤器中,我有: ffmpeg -re -i 'v
是否有用于Firebase 3存储的方法/规则来禁用文件更新或覆盖? 我为数据库找到了data.exists(),但没有为存储找到解决方案。 最佳答案 TL; DR:在Storage Security
我有两个 Docker Compose 文件,docker-compose.yml看起来像这样 version: '2' services: mongo: image: mongo:3.2
我需要覆盖 JPA 中的集合表吗?也许有人有想法 public class nationality{ @Embedded @AttributeOverrides({
嗨,我正在使用 WIX 和下面的代码将文件安装到目录中。 我的应用程序的工作方式是用户可以在该目录中复制他们自己的文件,覆盖他们喜欢的内容
我正在尝试为 Lua 中的字符串实现我自己的长度方法。 我已成功覆盖字符串的 len() 方法,但我不知道如何为 # 运算符执行此操作。 orig_len = string.len function
在Scala 2.10.4中,给出以下类: scala> class Foo { | val x = true | val f = if (x) 100 else 200
我想做上面的事情。 我过去覆盖了许多文件...... block ,模型,助手......但这个让我望而却步。 谁能看到我在这里做错了什么: (我编辑了这段代码......现在包括一些建议......
根据javadoc An instance method in a subclass with the same signature (name, plus the number and the ty
我有一段代码,只要有可用的新数据作为 InputStream 就会生成新数据。每次都覆盖同一个文件。有时文件在写入之前变为 0 kb。 Web 服务会定期读取这些文件。我需要避免文件为 0 字节的情况
我是一名优秀的程序员,十分优秀!