Search Unity

Accessing private data members from an inheriting class

Discussion in 'Scripting' started by Marble, Dec 13, 2006.

  1. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    I get protection level errors when I try to access a private variable from the class I have extended. Is there a different scope declaration I need to use besides private?

    Code (csharp):
    1. class QualitySetter extends Setter {
    2. private var override = super.colorOverride;
    3. }
    where colorOverride is declared private in class Setter.
     
  2. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Ok, I remember now. It's "protected."
     
  3. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Sounds like you should be using the protected access modifier.

    "Access is limited to the containing class or types derived from the containing class."

    From http://msdn2.microsoft.com/en-us/library/ba0a1yw2.aspx

    [Edit: You replied while I was typing--oh well, here for posterity now].
     
  4. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    :wink:

    Inheritance is still tricky for me.

    If I use GetComponent on type Car, will the Honda class that extends Car be returned if it's a component on my GO?
     
  5. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Ok, it appears the answer is yes. Another thing I got stuck on was that

    Code (csharp):
    1. function MethodFromMyOtherClass() {
    2. .....
    3. }
    4.  
    will not by default extend the extended class's method, but override it completely, so it needs to be:

    Code (csharp):
    1. function MethodFromMyOtherClass() {
    2. super.MethodFromMyOtherClass();
    3. .....
    4. }
    5.  
    whew.
     
  6. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    I'm fairly new to Unity, so I'm not sure how things like GetComponent respond to inheritance.

    The other thing that's a bit tricky with C# is the concept of polymorphism and using the virtual and override keywords.

    Let's say you have a base class, Car, and two classes that extend Car: Honda and Toyota.

    Let's say each class has a method, Honk(), that simply outputs:

    Car: "Beep! I'm a car!"
    Honda: "Beep! I'm a Honda!"
    Toyota: "Beep! I'm a Toyota!"

    Now, the concept of polymorphism is that you'll be able to treat both a Honda and a Toyota as a Car (because they have all of the methods and properties of a car).

    That is, this is legal:

    Car myCar = new Toyota();

    Now, if you just override Honk() in the Toyota class as you did above, calling myCar.Honk() will actually output "Beep! I'm a car!". What you'd probably want, though is for the Honk() function to route to the Toyota's version of it. That is, even though the myCar variable is of type Car, you want the compiler to realize that there's actually a Toyota in there.

    To do that, you'd mark the Honk() method as virtual in the parent class Car:

    Code (csharp):
    1.  
    2. public virtual void Honk()
    3. {
    4.    Debug.Log("Beep!  I'm a car!");
    5. }
    6.  
    And then in the Toyota class you'd mark is as override:

    Code (csharp):
    1.  
    2. public override void Honk()
    3. {
    4.     Debug.Log("Beep!  I'm a Toyota!");
    5. }
    6.  
    If you leave out the override keyword, it implicitly uses the new keyword, which tells the compiler that the function only applies to variables of type Toyota (but not if you have a variable of type Car that points to a Toyota).

    So if you have the Toyota Honk() as:

    Code (csharp):
    1.  
    2. public new void Honk()
    3. {
    4.     Debug.Log("Beep!  I'm a Toyota!");
    5. }
    6.  
    And do this:

    Code (csharp):
    1.  
    2. Car myCar1 = new Toyota();
    3. Toyota myCar2 = new Toyota();
    4.  
    5. myCar1.Honk();
    6. myCar2.Honk();
    7.  
    With the virtual/override combo, you'll get "Beep! I'm a Toyota!" for both honks. With the new keyword, or without any keywords, you'll get:

    Beep! I'm a Car!
    Beep! I'm a Toyota!


    Which is probably not what you want. In a game situation, it's pretty common to have an array of Enemy objects and then call a function like Attack() on each one and let whatever subclass the objects really are handle it. You'd have to use the virtual/override keywords for this.

    Hope that makes sense! It's a little late here, and my brain is quickly fading...
     
  7. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Yeah, that helps even though it's a bit of a pain. I wonder how much of this applies to Unity's Javascript (i.e. virtual, override, etc.).
     
  8. Talzor

    Talzor

    Joined:
    May 30, 2006
    Posts:
    197
    It might appear that way, but it doesn't. GetComponent always return an object of the type Component (as can be seen in the documentation). You then have to downcast this to the class you want it to be. Of cource, when you use JS all this happens more or less implicitly.
     
  9. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    You are both right. GetComponent returns the found component as type Component. (It's ducktyped in Javascript, so you will not have to do the downward typecasting unless you are using C#.)
    GetComponent returns the first component that is-a the type supplied as argument. I.e. it will also return subclasses of the type specified.
    This is useful. For example, as all components inherit from Component, it can be used as the argument to GetComponents to get a list of all attached components regardless of type:
    Code (csharp):
    1. var all_components = GetComponents(Component);
    If you want an exact type of component (and not a subclass), you will have to loop throught the result of GetComponents and explicitly test the type:
    Code (csharp):
    1. function GetComponentExact(type : System.Type) {
    2.    for(var candidate in GetComponents(type)) {
    3.       if(candidate.GetType() == type)
    4.          return candidate;
    5.    }
    6.    return null;
    7. }
     
  10. Talzor

    Talzor

    Joined:
    May 30, 2006
    Posts:
    197
    I didn't mean to imply that GetComponent wouldn't return the Honda, only that the returned type would always by Component. Sorry for the ambiguous post. :oops: