- Home /
Does Unity support multiple Inheritance?
Say I have these five classes:
class People extends MonoBehaviour { var name : string; var male : boolean; var fullAge: boolean;
function CanWalk () {...} }
class Females extends People { function Start () { male = false; } function TalkAlot () {...} }
class Males extends People { function Start () { male = true; } function PlaySoccer () {...} }
class Children extends People { function Start () { fullAge = false; } function MayPlayInMud () {...} }
class GrownUps extends People { function Start () { fullAge = true; } function HaveToWork () {...} }
Can I combine these classes by multiple Inheritance to a class "Boys" that inherits from "Males" and "Children" at the same time? In both UnityScript and C#? If so, how?
And if so, how can I make sure that I won't inherit from "Children" and "GrownUps" at the same time? (Would it give me an error or would one be overridden the other? If so, which one?)
Thanks & Greetz, Ky.
Answer by jashan · Dec 23, 2009 at 06:45 PM
I think most modern languages - including C# and UnityScript - have abandoned the concept of multiple inheritance. The reason is that it creates more problems than it solves, and in the end, it doesn't really give you much benefit. Usually, you can use interfaces (at least in C#) if you need different "types" of classes to provide the same methods.
To be honest, usually the need for multiple inheritance comes from design flaws - as your example illustrates: Instead of having this complex inheritance hierarchy with Females, Males, Children and GrownUps, your People class would be fully sufficient. Instead of using the Start method to somewhat statically assign the attributes the People class defines, you'd either assign those variables from script, or in the editor.
In the context of Unity, you could use one other concept I know is used to live peacefully without multiple inheritance: composite aggregation, i.e. creating composite objects that consist of multiple smaller objects. That's exactly what GameObjects are in Unity: A composite object that consists of one or many components.
So, you'd have your People class which defines the attributes people have (gender, age, name etc.), and a few MonoBehaviours which model the behaviors that females, males, children and grownups usually share (the methods / functions you have defined above). That way, you'll always attach "People" to your GameObject (and probably, you'd call it "Person" instead of people, as instances of that class are not "people" but just one single person).
Then, depending on what kind of person it is, you could add "MalePerson" or "FemalePerson", and "Adult" or "Child", which implement the methods you have defined above. You could even do some extra checks from "Person" that prevent that one game object is both male and female or both adult and child (if that makes sense in your game).
That way, I'd say you can do pretty much exactly what you want to do without having to use multiple inheritance - instead you use elegant, modern, object oriented software design ;-)
Ah, no worries ^^ I wasn't going to use it... I'm currently trying to figure out all that OOP-theory and found an article wich described the mulitInheritanceConcept and claimed C# used it. But it also noted that there's a dabate about its flaws... So both from that and from my own example I already figured that it would be messy and I (most likely) wouldn't have used it. But I like to be thorough so I was wondering if it was possible in Unity's C# and/or UnityScript to begin with... Thank you for clearing that =)
notes "Composite Aggregation" for my "Appendix of weird OOP-Terms" ^^ ... Just to be safe: "...you could add '$$anonymous$$alePerson' or 'FemalePerson'... " That would be another script on the game-object (that is: another class, which doesn't inherit from "Person") right? But it comunicates with "Person" and enables some of it's predefined $$anonymous$$onoBehaviours for males or females...?
Exactly ;-) ... that's the idea behind composition: You have a couple of objects, which are instances of a few different classes (there are also cases where you have compositions of multiple instances of the same class). Those objects are very "close" and can also interact very closely. In Unity, what you can use for this close interaction is "GetComponent()". For example, if using C#, you could use inside $$anonymous$$alePerson the following code: Person personInfo = GetComponent(); ... then you could access the person's age via personInfo.Age (if you've declared that as property).
... of course: That would be assu$$anonymous$$g that your game object has both a Person and $$anonymous$$alePerson script attached to it. To make sure you can rely on Person always being attached to game objects that you attach $$anonymous$$alePerson (or one of the others) to, you can use the RequireComponent attribute. See also: http://unity3d.com/support/documentation/ScriptReference/RequireComponent.html
Thank you =) Hmmm, I know from the tutorials that there's a RequireComponent for UnityScript, too. Wonder why they don't put it in the API as well... well, nvm, I can look it up =)
Answer by Peter Alexander · Dec 23, 2009 at 04:34 PM
You can do what you're describing, but note that the Unity invoked functions, such as Start and Update, do not behave like normal functions. Unity will always and only call those functions in the most derived class.
For example:
class Base : MonoBehaviour { private void Start() { Debug.Log("Base Start"); } }
class Derived : Base {
}
If you attached the derived script to a GameObject, the Start function will never be called. It must be in Derived for it to work, and no, making it virtual does not help the situation.
Though this doesn't quite entirely answer my question it's a very important point you make there... could this be fixed if I used "Awake" ins$$anonymous$$d of "Start"?
No, not a single $$anonymous$$onoBehaviour method called by Unity uses dynamic dispatch. Awake, Start, Update, LateUpdate, FixedUpdate, OnGUI etc. will only be called if they exist in the most derived class. They cannot be inherited.
This is a quite significant point, thank you for clearing that! =)
Answer by sotirosn · Jun 02, 2013 at 07:01 AM
This is how I go about multiple inheritance in unity: (sorry I use c# so this might be a little off syntax wise)
class Boys extends People implements IMale, IChildren {
var male:IMale;
var child:IChildren;
function Awake() {
male = gameObject.AddComponent(Male);
child = gameObject.AddComponent(Children);
}
function PlaySoccer() {
male.PlaySoccer();
}
function ChildThing() {
child.ChildThing();
}
}
Kind of ugly but your second choice is to copy and paste the implementations of secondary base classes around. I think C#'s choice not to implement multiple inheritance is a mistake, but Unity's uberness makes up for it.