繁体   English   中英

寻找更好的方法来扩展方法

[英]Looking for a better way to extend methods

我正在 Unity 中从事一个业余爱好项目。 我有针对我的角色的MonoBehaviour脚本,这些脚本使用组件对象来表示角色的每个行为。 当我创建新角色时,我从基础 class 继承了一个新的 class,无论哪个组件的行为不同。

当某些触发器发生时,我通过调用基 class 公开的Reset()方法将字符发送回其初始值 state,该方法将字段设置回其初始值。 我想知道如何通过 inheritance 链向下发送该呼叫。 现在,基数 class 有一个受保护的虚拟ChildReset() ,它在Reset()中调用,默认情况下不执行任何操作。 如果子类有要重置的字段,它们会覆盖此方法。 感觉这是一种非常尴尬的做法。

我喜欢实现类似于 Unity 使用的消息系统的想法。 如果单一行为不使用Update()消息,那么 class 就不会定义更新。 它消除了不必要的呼叫。 我不知道我会怎么做那样的事情。

非常感谢任何对此投入的想法。 我已经在下面写下了我的项目的结构方式,以防这些细节对答案有用。

public class Character : MonoBehaviour
{
    private Motion motionController;
    private Interaction characterInteractionController;
    //etc

    private void Update()
    {
        motionController.DoStuff();
        characterInteractionController.DoStuff();
    }

    private void Reset()
    {
        motionController.Reset();
        characterInteractionController.Reset();
    }

    private void OnEnable() => ResetTrigger.OnReset += Reset;
    private void OnDisable() => ResetTrigger.OnReset -= Reset;
}

public class Motion : Component {}
public class Interaction : Component {}

public abstract class Component
{
    public void Reset() 
    { 
        /* set fields to default values */ 
        ChildReset();
    }
    
    protected virtual void ChildReset() { }
    public abstract void DoStuff();
}

无需通过 inheritance 链向下发送呼叫。 您没有两个不同的对象。 子 class 的一个 object 包含在基 class 中声明的所有内容。为什么不直接使Reset()虚拟?

public abstract class Character : MonoBehaviour
{
    public virtual void Reset()
    {
        ...
    }
}

public class ChildCharacter : Character
{
    // If ChildCharacter has stuff to reset, override this method, otherwise don't!
    public override void Reset()
    {
        base.Reset(); // Call this to reset stuff from the base class.

        //TODO: reset child stuff.
    }
}

如果Reset在子 class 中被覆盖,则调用Reset将调用ChildCharacter.Reset() ,即使是在静态类型为Character的变量上调用也是如此。

    Character c = new ChildCharacter();
    c.Reset(); // calls ChildCharacter.Reset() when overridden

如果Reset未在子 class 中被覆盖,则即使在ChildCharacter上调用Reset也会调用Character.Reset()

    ChildCharacter child = new ChildCharacter();
    child.Reset(); // calls Character.Reset() when not overridden.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM