c# - Unity (C#) 中的继承变量问题(更改继承变量)

标签 c# variables inheritance unity-game-engine

抱歉,我对这个问题有点茫然。例如,假设我有一个基类Character和两个子类FriendlyCharacter和EnemyCharacter。我希望他们都继承健康等变量,但我不应该将角色中的健康变量公开对吧?我假设如果我更改了友好字符的公共(public)变量,它会更改所有健康实例,正确吗?

如何初始化Character以包含将由其他类继承的变量?一旦继承,这些类将拥有该变量自己的实例。我觉得必须重新初始化每个子类中的变量只会使基类中的初始化变得毫无意义。

如果有任何帮助,我将不胜感激。

最佳答案

您正在寻找的是接口(interface),或抽象/虚拟函数。一般来说,有两种技术:

public abstract class Character : MonoBehaviour
{
    public float m_Health { get; protected set; }
    protected abstract float DefaultHealth { get; }
    void Awake()
    {
        m_Health = DefaultHealth;
    }
}
public class Enemy : Character
{
    protected override float DefaultHealth { get { return 10; } }
}

(如果应该有一个基本实现并且重写是可选的,则使用虚函数而不是抽象函数。)当逻辑全部共享,但在子类中指定了一些不同的位时,使用上述模式。基类中的大函数调用可以在子类中指定的小函数。

第二种技术适用于当类在外界看来相同但在基本层面上功能不同时:

public interface ILiving
{
    float Health { get; }
}
public class Character : ILiving
{
    // implement health as a normal variable
    public float Health { get; protected set; }
}
public class OldMan : ILiving
{
    // implement health based on time until death at 2020
    public float Health { get { return (2020-DateTime.Now.Year)/20; } }
}

在这种情况下,两种类型都具有健康状况,但它们运行的​​逻辑不同。在外界看来,它们看起来是一样的,但它们却截然不同,不应该有任何共同的逻辑。

请注意,在 Unity 中,事情可能会变得困惑。由于我们被迫从 MonoBehaviour 继承(并且 C# 缺乏多重继承),因此有时我们无法在想要的地方使用继承。在这些情况下,我们可以通过使用接口(interface)、显式接口(interface)实现( protected 函数的合理模仿)和扩展方法来模拟继承。 (定义扩展方法的类将扮演基类的角色。)通常,当类想要成为两个类层次结构(基于两个不可调和的功能集)的一部分时,就会出现这种情况。在游戏中,盔甲、武器和法术可能都想参与升级系统。盔甲和武器是装备类别层次结构的一部分,但法术不是。因此相关数据被做成接口(interface)函数,共享代码被定义为扩展方法(因为盔甲和法术不共享公共(public)基类,除了MonoBehaviour)。

关于c# - Unity (C#) 中的继承变量问题(更改继承变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40097053/

相关文章:

c# - 如何在部署或推送之前或在 visual studio 中更改文件时添加版本号

c# - LINQ 有条件地添加联接

c# - 带有构造函数警告 "No parameterless constructor defined for this object"的自定义 Json.net JsonConverter

c# - 如何覆盖而不是隐藏 C# 子类中的成员变量(字段)?

c# - 长继承层次

c++ - 继承二级基类构造函数: silent error

c# - MVC 5 绕过 Windows 身份验证用户的表单例份验证

c++ - 如何为变量分配一个新对象

inheritance - Groovy在这里做什么?

javascript - 如果 POST 不为空则显示文本