Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by IanT · Sep 25, 2012 at 12:03 PM · inheritancenewoverridecomparison

Practical differences between overriding and shadowing Start(), Update()...

Hi,

I am looking for the most efficient way to "override" Unity's engine methods like Update() in C#.

Note: Amongst other purposes this is to ease the process of freezing all in-game objects when timeScale == 0. I don't want to use FixedUpdate() on objects because I need to access some members at each frame, and because I guess FixedUpdate() is more processor-heavy than Update(); but correct me if I'm wrong.

=> I make a base class called InGameBehaviour that inherits from MonoBehavior. All my scripts used in-game are subclasses of InGameBehavior, and their own Update() method may access InGameBehaviour.Update() using base.Update()

From what I read the "new" modifier in a method's declaration should hide the base method. However if I declare Update() in a subclass with "new protected void Update() {}", I can still access InGameBehaviour.Update() using base.Update()...

This is the same as if I overrode the method with "override protected void Update() {}": in both cases the base method can be accessed with base.Update(), and in both case the base method is not called unless I use base.Update().

So, is there a practical difference/benefit in using "override" instead of "new" (or vice versa), in a case like this where both methods have the same signature?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by hvilela · Sep 25, 2012 at 01:26 PM

Knowing When to Use Override and New Keywords (C# Programming Guide)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image IanT · Sep 25, 2012 at 01:49 PM 0
Share

Thanks for the link, it's very interesting! This point is actually worth knowing when accessing classes indirectly (would I have not known it I would've probably been much confused if the problem arose someday) So I guess it's always better to "properly" derive a method from another, i.e. using override.

avatar image
2

Answer by Bunny83 · Sep 25, 2012 at 02:15 PM

The main point of virtual functions are that you have a common interface in the base class and subclasses can override it. The important point is when you access your class via a baseclass reference.

An example:

 // Case 1: hiding
 public class MyBaseClass
 {
     public void Test()
     {
         Debug.Log("MyBaseClass::Test()");
     }
 }
 
 public class Derived1 : MyBaseClass
 {
     new public void Test()
     {
         Debug.Log("Derived1::Test()");
     }
 }

Our test case:

 Derived1 C1 = new Derived1();
 C1.Test();                      // --> "Derived1::Test()"
 MyBaseClass B = C1;
 B.Test();                       // --> "MyBaseClass::Test()"


Now the same case with a virtual function and override

 // Case 2: virtual and override
 public class MyBaseClass
 {
     public virtuel void Test()
     {
         Debug.Log("MyBaseClass::Test()");
     }
 }
 
 public class Derived1 : MyBaseClass
 {
     public override void Test()
     {
         Debug.Log("Derived1::Test()");
     }
 }

The same test case:

 Derived1 C1 = new Derived1();
 C1.Test();                      // --> "Derived1::Test()"
 MyBaseClass B = C1;
 B.Test();                       // --> "Derived1::Test()"

The point of inheritance is to define an exact behaviour for your derived class, no matter how you use it. When you use the base keyword you always access the function from the base class. You can't remove the base class behaviour in your derived class. The base class is what it is. Virtual functions can be overridden, but with the "base" keyword you always reach the baseclass itself.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image IanT · Sep 25, 2012 at 09:07 PM 0
Share

Good class about inheritance! I'm still confused about the fact that the main role of the "new" modifier is to hide the base member from the overridden member – at least that's how it is described in C# reference – but all examples seem to show the other way around: it's more like if there's a "broken link" from the base member to the overridden member, but the communication from the overridden member to the base member still works like a regular override... But at least I got the facts, and I can go along with it. :)

Edit: ...I think I got all of it! :) Thanks Bunny for your enlightening example!

avatar image Bunny83 · Sep 26, 2012 at 04:48 PM 1
Share

Well, the important thing is that the base class and your derived class is not something totally different. The derived class is also a base class. When you just declare the same method that already exists in the base class in your derived class you hide the original method which is also part of your derived class.

Hiding elements will cause compiler warnings because this should generally be avoided. The "new" keyword just tells the compiler you want to hide it on purpose.

avatar image IanT · Sep 29, 2012 at 10:17 AM 0
Share

BTW Thank you for this further explanation. It's now perfectly clear to me!

avatar image whydoidoit · Sep 29, 2012 at 12:17 PM 1
Share

There is a special Unity added confusion that can arise with Unity functions like Update etc - that is that as you never call Update yourself - which one get called? The answer is that it is the one in the most derived class which is called.

The general rule with this kind of standard method is do not make calls like Update or Start virtual if the base class has processing that should always happen - for example you would write a concrete implementation of Update in your base class and defer processing to a virtual function - perhaps called OnUpdate. This allows for both standard handling and derived class handling and removes the fragility of forgetting to call a base class's method when it has something that must happen. When you do this it is a compiler warning when you write a new Update function in a derived class, so you are re$$anonymous$$ded that you shouldn't do that (or do it with the knowledge of the effect by adding the new keyword).

avatar image IanT · Oct 01, 2012 at 09:52 AM 0
Share

Thx. At first I didn't want to add my own parallel implementation of Update() because I didn't want to make a useless function call every frame on every object. So I explicitely declared base Update() virtual (and protected) and explicitely declared derived Update() override. But as you say, it was not secured, I could still implicitely hide a base Update() without any warning from the compiler. I realize I was going after nickel and dime and the involved risk may not worth it, so I made my own, strongly typed overridden, myUpdate().

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Overriding a function. 1 Answer

Create a new script object from a class which inherits from MonoBehavior 4 Answers

Can't Override Virtual Method In Inherited Class 1 Answer

How do I override objects that aren't in the Hierarchy? 0 Answers

Overriding a subtype's variable with its own subtype 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges