C#继承和成员隐藏

Var*_*lex 1 c# inheritance

我正在Unity游戏引擎中开发2D空间射击游戏.

我有一个基类,包含在所有敌方太空船之间共享的变量,并且该基类包含要由派生类的每个实例调用的函数.以此void Start()功能为例:

基类

public class EnemyBaseScript : MonoBehaviour 
{
    // some public/protected variables here

    protected void Start () 
    {
         // some initializations shared among all derived classes
    }
.
.
.
}
Run Code Online (Sandbox Code Playgroud)

派生类

public class L1EnemyScript : EnemyBaseScript 
{       
    // Use this for initialization
    void Start () 
    {
        base.Start ();  // common member initializations
        hp = 8;         // hp initialized only for this type of enemy
        speed = -0.02f; // so does speed variable
    }
}
Run Code Online (Sandbox Code Playgroud)

我想你应该已经明白了.我希望在base.Start()函数中完成常见的初始化,并在此Start()函数中完成特定于类的初始化.但是,我得到警告:

Assets/Scripts/L1EnemyScript.cs(7,14):警告CS0108:L1EnemyScript.Start()隐藏继承的成员EnemyBaseScript.Start().如果要隐藏,请使用new关键字

我缺乏OOP和C#的经验,那么按照我的想法做正确的方法是什么?这个警告意味着什么,我该怎么做?

小智 7

在C#中,继承具有相同函数签名的函数将隐藏前一个函数.

以微软网站为例:

class Base
{
   public void F() {}
}
class Derived: Base
{
   public void F() {}      // Warning, hiding an inherited name
}
Run Code Online (Sandbox Code Playgroud)

但是隐藏函数可能不是你想要的:

class Base
{
   public static void F() {}
}
class Derived: Base
{
   new private static void F() {}   // Hides Base.F in Derived only
}
class MoreDerived: Derived
{
   static void G() { F(); }         // Invokes Base.F
}
Run Code Online (Sandbox Code Playgroud)

相反,你可以做的是让你的基本功能"虚拟":

public class EnemyBaseScript : MonoBehaviour 
{
    // some public/protected variables here

    public virtual void Start () 
    {
         // some initializations shared among all derived classes
    }
.
.
.
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以覆盖它:

public class L1EnemyScript : EnemyBaseScript 
{       
    // Use this for initialization
    public override void Start () 
    {
        base.Start ();  // common member initializations
        hp = 8;         // hp initialized only for this type of enemy
        speed = -0.02f; // so does speed variable
    }
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 5

您需要告诉编译器Start应该被覆盖:

protected virtual void Start () { ... }
Run Code Online (Sandbox Code Playgroud)

而且你实际上是在你的派生类中故意重写它:

protected override void Start ()  { ... }
Run Code Online (Sandbox Code Playgroud)

看到的文档virtualoverride参考; 有更多的信息在这里.

您当前的代码定义了两个独立的Start方法,这些方法碰巧共享相同的名称,但没有其他相关的方