Reputation: 3463
I'm developing a 2D space-shooter in Unity game engine.
I have a base class containing the variables shared among all the enemy space ships and that base class contains functions that are meant to be called by every instance of the derived classes. Take this void Start()
function for example:
Base Class
public class EnemyBaseScript : MonoBehaviour
{
// some public/protected variables here
protected void Start ()
{
// some initializations shared among all derived classes
}
.
.
.
}
Derived Class
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
}
}
I think you get the idea. I want the common initalizations to be done in the base.Start()
function and for the class-specific initalizations to be done in this Start()
function. However, I get the warning:
Assets/Scripts/L1EnemyScript.cs(7,14): warning CS0108:
L1EnemyScript.Start()
hides inherited memberEnemyBaseScript.Start()
. Use the new keyword if hiding was intended
I lack experience in OOP and C#, so what is the correct way to do what I think? What does this warning mean and how can I do it right?
Upvotes: 2
Views: 2953
Reputation: 9648
In C#, methods/properties are non-virtual by default. You must declare the method/property virtual
if you wish to override
it in the subclass. If you do not then:
EnemyBaseScript s = new LIEnemyScript();
s.Start(); // calls EnemyBaseScript.Start()
while
L1EnemyScript s = new L1EnemyScript();
s.Start(); // calls L1EnemyScript.Start()
What you want is to make the method virtual in the base class and override it in the subclass
class EnemyBaseScript
{
protected virtual void Start()
{
//...
}
}
class L1EnemyBaseScript : EnemyBaseScript
{
protected override void Start()
{
base.Start();
//...
}
}
Upvotes: 1
Reputation:
In C#, inheriting a function with the same function signature will hide the previous one.
Take the example from Microsoft's website:
class Base
{
public void F() {}
}
class Derived: Base
{
public void F() {} // Warning, hiding an inherited name
}
However hiding the function is probably not what you want:
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
}
Instead what you could do is make your base function "virtual":
public class EnemyBaseScript : MonoBehaviour
{
// some public/protected variables here
public virtual void Start ()
{
// some initializations shared among all derived classes
}
.
.
.
}
Then we can override it:
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
}
}
Upvotes: 7
Reputation: 437734
You need to tell the compiler that Start
is supposed to be overridden:
protected virtual void Start () { ... }
and that you are in fact overriding it on purpose in your derived class:
protected override void Start () { ... }
See the documentation for virtual
and override
for reference; there is more information here.
You current code defines two separate Start
methods which happen to share the same name but are not otherwise related.
Upvotes: 5