- Home /
Question about Overriding
This may be a stupid question to ask but I don't understand why this is happening as to me, it shouldn't.
I have 3 scripts, A Objects script, A Floating Object script and a Asteroid script. The asteroid script Inherits the floating object script and the floating object script Inherits the objects script.
I have a protected void Update method in the Objects script and a protected virtual void Update in the floating object script. Basically what I don't understand is how everything still works since the floating object's Update method isn't overriding the objects Update method but I still need to call the base Update method and still allows me to use my own methods within the floating object script.
I basically thought that if you wanted to add your own code into a parents Update method then you needed to override it and call the base method first but I'm not here and it still works correctly as if I was overriding the base Update method.
I hope any of that makes sense. Here are the methods I'm referring too, first method in the Objects script and the second method in the Floating Objects script:
protected void Update()
{
if(!GetComponent<SpriteRenderer>().isVisible)
{
destroyTimer += Time.deltaTime;
if(destroyTimer >= destroyDelay)
{
Destroy(gameObject);
}
}
}
protected virtual void Update()
{
base.Update();
RotateObject();
}
I was wondering, if you understand it, if you could explain to me why everything still works correctly despite me not overriding the base Update method and I'm sorry if this is a stupid question to ask.
Answer by jdean300 · Jul 14, 2016 at 05:47 AM
So to be clear, you have something like this:
public class Object : MonoBehaviour{
protected void Update() {
Debug.Log("Inside Object"); //I'll use this for a demo later
}
}
public class FloatingObject : MonoBeheaviour{
protected virtual void Update{
base.Update();
Debug.Log("Inside Floating Object"); //I'll use this for a demo later
}
}
When Update is called on FloatingObject, your output is:
Inside Object
Inside FloatingObject
And you are wondering why/how this is working.
Well first, you are correct in saying that you are not overriding the Update method inside Object:
GameObject obj = /*get a reference to an object with a FloatingObject component*/;
FloatingObject floating = obj.GetComponent<FloatingObject>();
floating.Update(); //logs "Inside Object, Inside Floating Object"
Object baseCast = (Object)floating;
baseCast.Update(); //This will log "Inside Object" because you are not overriding. If you were overriding, you'd have the same output as above
I am guessing your confusion is that you are able to call base.Update()
. The fact that you can do that actually has nothing to do with overriding. When you prefix a method call with base.
all that happens is the given method from the base class is called. You could call ANY method that exists in the base class inside of FloatingObject.Update. For example, lets say we added public void ObjectMethod(){}
to the Object class. This would still be perfectly valid:
//Inside FloatingObject
protected virtual void Update() {
base.ObjectMethod();
//Other update stuff here
}
All base.
does is restrict the call to methods existing in the base class. When you override methods, this allows you to call the base class version of Update. However, you do not NEED to call the base method. If you wanted to completely replace Object.Update with FloatingObject.Update you can ignore the base.Update call.
The thing I'm getting confused about (And I understand what I'm confused about more XD) is why should I use override when I can keep using virtual?. Since if base.Update() just calls the base update method and I need to use virtual or override before I can call the base.Update() method. Why do I need to use the override key word when I can just keep virtual. It's not easy to explain really...
This is in the objects script:
protected virtual void Update()
{
if(!GetComponent<SpriteRenderer>().isVisible)
{
destroyTimer += Time.deltaTime;
if(destroyTimer >= destroyDelay)
{
Destroy(gameObject);
}
}
}
This is in the FloatingObjects script which inherits Objects:
protected virtual void Update()
{
base.Update();
RotateObject();
}
And this is in a new script I've made which inherits FloatingObject:
protected virtual void Update()
{
base.Update();
destroyTimer += Time.deltaTime;
if(destroyTimer >= destroyDelay)
{
Destroy(gameObject);
}
}
All of the Update methods use the virtual keyword and work perfectly, allowing me to use the base.Update() method and my own code, the same if I was using the override keyword in FloatingObject and the new script. And that's why I'm confused, why use override when I can keep using virtual since it still works perfectly?
I think you're confused about the purpose of overriding. Overriding replaces the base class version of the method so that if you down-cast a child to the base class and then call the overloaded method, you will end up calling the overriding version:
public class Base{
public virtual void Do(){ Debug.Log("Hello from Base");}
}
public class Child {
public override void Do() { Debug.Log("Hello from Child");}
}
Child c = new Child();
c.Do(); //Prints "Hello from Child"
Base b = (Base)c; //Down-cast a child to the base
b.Do(); //Prints "Hello from Child"
In the second Do call, even though b has been cast to Base, it is still an instance of Child, and because the Do method has been overridden, the overridden version of Do is called.
For what you are doing, you can drop the virtual part completely. However, if you down-cast a FloatingObject to an Object, you're going to end up calling Objects methods, which may or may not be what you want.
I understand... sort of but thank you.
I've still got a lot to learn so. I've only started to fully learn Object-Oriented when i should of started ages ago and Polymorphism is one thing I don't understand that well :P