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
0
Question by Wendek · Nov 15, 2013 at 06:39 PM · c#inheritancehiding

Hiding an inherited variable : "The same field name is serialized multiple names in the class or it's parent class.

Hello,

My situation is the following : I have a general "WorldObject" class, with a "player" member that references the owner of the object. But I have three "Player" classes : a general one and two derived ones (made for different factions in the game, each type of player has specific methods and variables). Now what I would like to do (which may not be possible, from what I'm seeing so far) is to "change" the type of the "player" variable depending on the faction. That is, I want my "player" field to be of type "HumanPlayer" when used in a "HumanUnit" (which is another class inheriting from WorldObject) and of type "OrcPlayer" if used in an "OrcUnit". This way when I call "player.MethodSpecificToHumanPlayer())" it works and I don't have to cast every single time because by default I have access to a "HumanPlayer" and not a simple "Player".

I thought the whole "hiding" thing was made for this but apparently it only works with methods or properties. At the moment my "player" field is protected and I get that weird error in the title, which I don't really understand and searching for the others that have had the same error yielded no result.

Of course there are easy ways around that, the simplest being to create another variable named "hPlayer" of type "HumanPlayer" and then use both. That's probably what I'll end up doing anyway, but for future reference I'd like to know if what I am trying to do is at least possible or not.

Thanks in advance. Also sorry for asking something that's probably close to programmation-blasphemy. :p

Edit : since it seems I'm getting misunderstood I'll add some pseudo-code of the problem.

 class A {
 protected Player player;
 }
 
 class B : A {
 protected HumanPlayer player;
 
 private void Foo()
 {
 player.AMethodThatExistsInHumanPlayerButNotInPlayer();
 }
 }
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

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by YoungDevelops · Dec 01, 2017 at 03:13 AM

This is so many years late, but if anyone needs this in the future, it may be useful. I had the same issue, but I found that it means that a private variable is in the parent class that is in the child class as well. The solution is to set the repeated variables in the parent class to protected rather than private, then remove the variables from the child class.

Comment
Add comment · 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
0

Answer by fafase · Nov 15, 2013 at 06:45 PM

Ok I think you are after virtual and override.

 TopClass{
    public virtual void MyMethod(){}
 }
 
 SubClass:TopClass{
    public override void MyMethod(){}
 }
 OtherSub:TopClass{
    public override void MyMethod(){}
 }

Now in your class:

 TopClass objRef;
 
 void Start(){
     objRef.MyMethod();
 }


Believe it or not but if you pass an object of the sub type, even though your reference is of top class the compiler will look into MyMethod and find it as virtual. So it will look down the object on case that object would have any sub class implementing that virtual method and it will call the sub class if there. This is opposed to non virtual method that if you implement the same method down the hierarchy, it will hide the top one and the compiler will suggest you to use new if intended. This would result in the method from the level the reference points to.

Comment
Add comment · Show 3 · 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 Wendek · Nov 15, 2013 at 07:00 PM 0
Share

No I'm sorry but that's not the problem I'm talking about. I understand overriding methods but I'm asking how to hide/override VARIABLES. Let's use a quick code example because I suppose I wasn't clear in my original formulation :

 Class A
 {
 protected int number;
 }
 
 Class B : A
 {
 protected float number; //Basically I want to call "number" as a float for this class with the same name
 }

Edit : example might be a bit inacurrate because I don't think "float" inherits from int. In my case though, I'm actually "replacing" the variable's type by a subtype. Wanted to precise in case it changes anything.

avatar image fafase · Nov 15, 2013 at 07:09 PM 0
Share

It seems you want to use the same name for a different variable and the answer is that it is not possible, to my knowledge. It is not a question of type (and yes float does not inherits from int) but more a question of variable management. How can the compiler figure out which one you are meaning when simply using:

 number = 2;

You have to come up with a different logic for your class.

avatar image Wendek · Nov 15, 2013 at 07:32 PM 0
Share

Well that's where that shiny "new" keyword comes into play ! Basically when I declare "protected float number", Unity tells me that it "hides the parent class declaration", and that I should use "new" if that hiding is intended. Except that in the end, whether I use "new" or not in my declaration, it doesn't work.

Welp, guess I'll just create another variable and will remember this for later.

avatar image
0

Answer by TehWardy · May 11, 2014 at 10:34 AM

Correct me if im wrong here but this is actually a fundamental flaw in your design.

Lets take unity out of the problem here and just look at c# as a language. If i override a variable I cannot change it's type in this manner because that would give a variable a different meaning and behaviour.

You could do this however ...

 Class A {}
 
 Class B : A
 {
     protected int number;
 }
  
 Class C : A
 {
     protected float number; 
 }

This way you can access number as the right type given that you have an object of the right type ...

 var p = A, B, or C type
 
 // property number not available
 var baseType = ((A)p)
 
 // property number is of type int
 var bType = ((B)p);
 
 // property number is of type float
 var cType = ((C)p);

but given that you have B / C types you can now no longer cast between them as they are considered to be fundamentally different.

Comment
Add comment · 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
0

Answer by Dray · Dec 01, 2017 at 08:16 AM

Hiding methods and variables is not made for changing the return type, if you override a function you'll have to use the same parameters, return type and name or it will be an independent function. Now for the player variable, I wouldn't override it at all, it's redundant. 'HumanPlayer' is a Player in that case so why not just keep that as it is and add a function that casts the type to your Human- or OrcPlayer.

Or to make it even a bit cleaner you could implement a generic abstract 'Unit' class with a dynamic Type like this:

 // T is your variable type. The where part is optional but I recommend using it here
 public abstract class Unit<T> where T : Player
 {
     protected T player;
 }
 
 // player type here will be a HumanPlayer
 public class HumanPlayerUnit : Unit<HumanPlayer>
 {
     public HumanPlayer GetPlayer() {
         return player;
     }
 }
 
 // player type here will be a OrcPlayer
 public class OrcPlayerUnit : Unit<OrcPlayer>
 {
     public OrcPlayer GetPlayer() {
         return player;
     }
 
     public void DoSomething() {
         player.OnlyOrcPlayerMethod(); // works because the player is an OrcPlayer allready
     }    
 }    

edit: actually, let's turn this into an answer

Comment
Add comment · 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

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

20 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

An OS design issue: File types associated with their appropriate programs 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Derived Class Fields 3 Answers

Inherited member variables not set to base value c# 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