Search Unity

Problem with re writing the constructor of an inherited class

Discussion in 'Scripting' started by Stickworm, Nov 22, 2012.

  1. Stickworm

    Stickworm

    Joined:
    Apr 24, 2011
    Posts:
    67
    Hello could somebody please explain to me why when trying to overwrite the constructor function for this sub class it will only work if the original constructor takes no parameters? It I do give it parameters (which match the ones I want to pass to the new version of the function) I get the error:

    BCE0024: The type 'BaseClass' does not have a visible constructor that matches the argument list '()'.


    Code (csharp):
    1. class BaseClass{
    2.     function BaseClass(incoming: int){      //Does not work
    3.     //function BaseClass(){             //Works
    4.     }
    5. }
    6.  
    7. class SubClass extends BaseClass{
    8.     function SubClass(incoming: int){
    9.     }
    10. }
    11.  
     
    Last edited: Nov 22, 2012
  2. Stickworm

    Stickworm

    Joined:
    Apr 24, 2011
    Posts:
    67
    Well after months of having no clue how to do this and then finally posting, an hour later I've worked it out. You have to call Super in the new constructor and pass the variables. So I assume Unity was doing this automatically before but with out the parameters explicitly stated it was having difficulties.

    Code (csharp):
    1. class BaseClass{
    2.     function BaseClass(incoming: int){      //Now DOES work
    3.     //function BaseClass(){                 //No longer works
    4.  
    5.     }
    6. }
    7.  
    8. class SubClass extends BaseClass{
    9.  
    10.     function SubClass(incoming: int){
    11.         super(incoming);
    12.     }
    13. }
    If anyone's got any comments on this or more helpful information that would still be welcome thank you.
     
  3. Lypheus

    Lypheus

    Joined:
    Apr 16, 2010
    Posts:
    664
    This is really a discussion on OOP but in short this is why that you're seeing that error without the use of super, note I'm coming from a Java world and using C# mainly due to Unity3D, but i'm pretty sure this is accurate enough in a UnityScript context as well.

    When you define a class, say BaseClass in your example, you do one of two things regarding constructors:

    A. You define NO constructors - in this case, UnityScript will "assume" a default constructor, one with no arguments.
    B. You define ONE OR MORE constructors - when you do this, you're now saying "this is the only means by which this class can be created", and UnityScript *will not* create a default no argument constructor for you, this is left up to you to do if you want it since you have specified one or more constructors.

    So if you define BaseClass with a constructor BaseClass(int), what that is saying is that the only way by which you may instantiate a BaseClass, is by providing an int (incoming). Trying to create it using a float, double, string ... or no parameter at all even ... is INVALID.

    If you want to allow BaseClass to be created for more cases than just BaseClass(int), you'll need to specify more constructors, so for instance, you could create a second constructor BaseClass() to ensure you have a default constructor or if you like, you could even just specify a default constructor by itself to be explicit.

    Now - SubClass you created to "be a" type of BaseClass. When you specified a constructor SubClass(int), that is fine it just means SubClass requires an int to be created as per discussion above. The problem is, if BaseClass requires an int too (see your first example), then when SubClass is instantiated, it tries to in turn, first instantiate a BaseClass to build itself from (not quite but close enough for our purposes). Anyhow, so now in the code:

    Code (csharp):
    1.  
    2.    function SubClass(incoming: int)
    3.    {
    4.         // nothing here means it attempts to fallback on a DEFAULT NO-ARG constructor to invoke parent class
    5.    }
    6.  
    So since you have no code, it assumes default no-arg, and it tries to create a BaseClass. But BaseClass ONLY allows for (int) and does not have a default constructor and therefore fails.

    This is why you must specify super(int) - super essentially just tells UnityScript that "hey instead of using a default no-arg constructor, use THIS constructor to build BaseClass instead!".

    Hopefully i've articulated that well enough - happy coding!
     
  4. Stickworm

    Stickworm

    Joined:
    Apr 24, 2011
    Posts:
    67
    Hey Lypheus, thanks for your reply I've only just seen it.

    Yes this does seem to be the situation though it seemed strange to me that Unity would fall back on a Base Class that took no parameters when I had only defined one that did require parameters. It does actually make sense that you must explicitly state what you want passing to the base class (as opposed to automatically passing the same arguments as the second) I simply couldn't see how to actually do this documented anywhere. In the real world situation I would not have wanted to create a Base Class that took no parameters to 'ensure you have a default constructor' as I needed that value set.

    Cheers