我正在Unity游戏引擎中开发2D太空射击游戏。
我有一个基类,包含在所有敌方太空船中共享的变量,并且该基类包含要由派生类的每个实例调用的函数。以此void Start()
函数为例:
基类
public class EnemyBaseScript : MonoBehaviour
{
// some public/protected variables here
protected void Start ()
{
// some initializations shared among all derived classes
}
.
.
.
}
派生类
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
}
}
我想你明白了。我希望在base.Start()
函数中完成常见的初始化,并在此Start()
函数中完成特定于类的初始化。但是,我收到了警告:
Assets / Scripts / L1EnemyScript.cs(7,14):警告CS0108:
,请使用new关键字L1EnemyScript.Start()
隐藏继承的成员EnemyBaseScript.Start()
。如果要隐藏
我缺乏OOP和C#的经验,那么按照我的想法做正确的方法是什么?这个警告意味着什么,我该怎么做?
答案 0 :(得分:7)
在C#中,继承具有相同功能签名的函数将隐藏前一个。
Take the example from Microsoft's website:
class Base
{
public void F() {}
}
class Derived: Base
{
public void F() {} // Warning, hiding an inherited name
}
然而隐藏功能可能不是你想要的:
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
}
相反,你可以做的是使你的基本功能"虚拟":
public class EnemyBaseScript : MonoBehaviour
{
// some public/protected variables here
public virtual void Start ()
{
// some initializations shared among all derived classes
}
.
.
.
}
然后我们可以覆盖它:
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
}
}
答案 1 :(得分:5)
您需要告诉编译器应该覆盖Start
:
protected virtual void Start () { ... }
并且你实际上是在你的派生类中故意覆盖它:
protected override void Start () { ... }
请参阅virtual
和override
的文档以供参考;有更多信息here。
您当前的代码定义了两个独立的Start
方法,这些方法碰巧共享相同的名称,但在其他方面没有相关性。
答案 2 :(得分:0)
在C#中,默认情况下方法/属性是非虚拟的。如果您希望在子类中virtual
,则必须声明方法/属性override
。如果你不这样做:
EnemyBaseScript s = new LIEnemyScript();
s.Start(); // calls EnemyBaseScript.Start()
,而
L1EnemyScript s = new L1EnemyScript();
s.Start(); // calls L1EnemyScript.Start()
你想要的是在基类中使方法虚拟化并在子类中重写它
class EnemyBaseScript
{
protected virtual void Start()
{
//...
}
}
class L1EnemyBaseScript : EnemyBaseScript
{
protected override void Start()
{
base.Start();
//...
}
}