I'm used to c++ classes, where I created classes describing some behavior like : clickable, physical, visible, etc, etc. It's quite usual for me to inherit from multiple classes.

Godot don't let you inherit from multiple classes and I wonder how am I supposed to write logical, re-usable code than? I really don't want to create separate "clickable" object inside my button object because... It's weird... at least to me. Composition doesn't always fit into what we do. My object doesn't "has" clickable. It "is" clickable, so I want to inherit that. I would have to connect artificial "clickable" object to my object that is actually clickable, which seems like a lot of code that I need in one file and that I wanted to avoid in first place by... just inheriting from clickable and overriding some functions like onClick, onRelease, etc. On the other hand I could just inherit from clickable, but I cannot inherit from multiple classes than, so what if I will want to move some other property that I found might be useful to re-use in future - I will not be able too, because this new property either will HAVE TO inherit form clickable, or clickable will HAVE TO inherit from that new property.

After writing that I came to realisation that it's just inherently flawed design... Use composition only if you don't like inheritance. That would be more appropriate, because inheriting form canvasItem properties such as modulate or light-mask doesn't make any sense for Position2D or Camera2D. I think having access to unused properties is sign of bad design.

There is literally no point in using inheritance if you can only inherit from one class. The point is : sooner (or even sooner) you will have to add second property and than inheriting first property will be in-appropriate, as you want to treat both properties equally - the same way, so you should move from inheriting to "containing" those and wrapping a lot of code to access "contained" object.

My thesis is : single inheritance rule is flawed. Use either : (multiple inheritance) / (none at all) / (irrational code - sometimes you inherit properties, sometimes you contain them). I invite you to the discussion if you think it's wrong.

  • My examples may not be ideal, but I strongly believe there would be better ones proving my point.

** That's all not to be said I won't use Godot, still I very much like it for other things. I just came to conclusion that single inheritance is super flawed and wanted to share my thoughts.

Assuming it works the same in source/c++ as it does in GDScript then you would extend a class that extrends a class that extends a class. etc. etc.

If you want to discuss the engine core design though I think you are better off taking it to the tracker. It's more relevant in there and will attract the eyes of more relevant community members i.e. the core engine developers.

If you've got specific proposals in mind then this is the place for it: https://github.com/godotengine/godot-proposals/issues

And for issues and bugs it's this: https://github.com/godotengine/godot/issues

Thanks for suggestions, I might poke that topic in tracker therefore.

Many OO languages only support single inheritance.

C# and Java are two major ones.

Java uses interfaces to support most of the value of multiple inheritance. Multiple inheritance is a large can of worms, adding a ton of complexity to a language

As Mega mentions here you can 'subclass' scripts by saying

extends "res://...super-script-name"

But Godot scripts are not classes.

Your gdscript can be applied to add properties and functions to any subclass of the godot intrinsic directly extended by your script or a super script of your script. You need to think of scripts as "mixins" that extend the properties and functions of some intrinsic godot class instance. Here I mean those classes built into the engine: Object, Node, Spatial, Resource, MeshInstance etc. The object types offered to you when using the editor add function.

Remember that a reference to any script you write that is associated with a godot intrinsic can be accessed by get_script() and you can change the script by set_script(). In this sense gdscript is a bit more javascript-ish, in that you can paste a host of properties or functions to an existing instance, but is much more structured than javascript.

Godot is structured differently. You extend functionality by composition of nodes more than inheritance. This means your scene tree might have an organizing node followed by a clickable, physics-body, meshes and what have you, which may be organized in tree as you see fit. You associate the functionality to these components by adding scripts to them

In my case I have a thinga-ma-bob scene in my project that represents a little tablet for scribbling on in a game instance.

The tablet has the elements for representing itself in game, and all the actions that support doing its tablet-y things but I have distinct nodes to process inputs (because the file size was getting big) and nodes for the component of the tablet have scripts to handle functionality relevant only to them.

It is actually nice because now the scripts in the scene factor out input handling from the code representing the object and code related to child nodes is bound to them instead of being swept into the root node.

It's going MVC ish.

"Multiple inheritance is a large can of worms, adding a ton of complexity to a language." I simply do not agree with that at all (unless you mean it's hard to implement in language, than I don't have experience thus opinion). As long as it works as in c++ and programmer don't do some design mistakes - multiple inheritance is not mistake in itself. Classes should inherit traits not parents.

I think I don't understand those principles, but I just don't like them. I for example don't want to make node called clickable... Thats complete nonsence to me... Nodes cannot represent traits.. With heavy focus on re-using code I will end up with 1'000 nodes sooner than later and it's not good for scene loading. Instead of making next node, I think I could add variable var clickable = load("clickable.gd") and connect it's onClick/onRelease/onHover methods to button script functions... But that would be as much code as just re-writing all code I don't want to rewrite in first place... Whole point is I don't want to deal with event.mouse.button.left.released'alike code in every clickable object. What I wanted was inherit from clickable and use onClick/onRelease methods as I use event, input _ready right now : I can override it or not and by default they don't do anything....

Huh I actually have idea. In clickable.gd I could request argument in init() and connect to those onClick, etc methods if they are present. Than just add variable that is equal to load("clickable.gd").new(self) and... Have that new capability to use set up functions... Ah, yet I would have to call nested input from container _input.

I can see if I could inherit from 2 objects that use input() it could be ambiguous, but than script should just crash with ambiguous code error and I would just overwrite input() in parent class with only 2 lines : child1::input() child2::input(), or other way around or only one of those, or none of those. Ambiguity problem solved.

(unless you mean it's hard to implement in language, than I don't have experience thus opinion). Yes, I mean that. I have little issue writing C++ or using multiple inheritance, but C++'s compiler is one of the most complicated compilers there are. Parsing then interpreting the parse tree is 'interesting' for C++.

So I never said it was a mistake, but that supporting it makes for a very complicated parser, something that is a negative for a scripting language and presents much more of a challenge of casual programming or the uninitiated. The latter reason was why the designers of Java chose single inheritance.

Whole point is I don't want to deal with event.mouse.button.left.released'alike code in every clickable object. What I wanted was inherit from clickable and use onClick/onRelease methods as I use event, input _ready right now : I can override it or not and by default they don't do anything....

1) Have your onClick and onRelease calls emit a signal and wire up a method to it if you want functionality. Or 2) your clickable can simply reference the containing node and you can define functions there to perform the actions you want. In standard UI frameworks events are often 'bubbled' up through the display hierarchy like:

root container with default handle_click() { if parent has handle_click, invoke it} clickable._handle_click() { does stuff directory or goes to root and calls something there }

Plus godot already has a multitude of 2d UI components that handle all that for you

Yes, I mean that. Oh, than my whole paragraph is pointless, I misunderstood that it was about usage of multi - inheritance and focused whole comment on defending that. 1) 2) Yeah, that's what i settled on after all. It is some solution with almost as little job as inheriting it. Question of solving that "properely" in Godot was actually whole point I came here. Plus godot already has a multitude of 2d UI components that handle all that for you I often spend too little time looking for right element, for example I almost implemented tileMap before finding it :# but often times pre-built components don't give me as much flexibility as I like. Aand I found I could get signals from TextureButton to my script. I will just have to add onHover/onMouseLeave signals. But it's good you helped me find generic solution for "simmilar problems" which will not have appropriate - ready to use element in editor.

2 years later

Allowing multiple inheritance makes the rules about function overloads and virtual dispatch decidedly more tricky, as well as the language implementation around object layouts. These impact language designers/implementors quite a bit, and raise the already high bar to get a language done, stable and adopted.

It is simple to think this way, if class A inherits from multiple classes, then the class A will have the same grandparent class multiple times, this means the code will be complicated and a series of bugs will go unacknowledged. Personally, I think multiple inheritance has a bad rap, and that a well done system of trait style composition would be really powerful/useful... but there are a lot of ways that it can be implemented badly, and a lot of reasons it's not a good idea in a language like C++.

Welcome :-)

I too think MI is smelly, though I have thoughtlessly used it. I also think C++ is not a particularly well thought through programming language.

But let's Bjarne Stroustrup have a word:

People quite correctly say that you don't need multiple inheritance, because anything you can do with multiple inheritance you can also do with single inheritance. You just use the delegation trick I mentioned. Furthermore, you don't need any inheritance at all, because anything you do with single inheritance you can also do without inheritance by forwarding through a class. Actually, you don't need any classes either, because you can do it all with pointers and data structures. But why would you want to do that? When is it convenient to use the language facilities? When would you prefer a workaround? I've seen cases where multiple inheritance is useful, and I've even seen cases where quite complicated multiple inheritance is useful. Generally, I prefer to use the facilities offered by the language to doing workarounds.

So, should we think that the language creator thinks C++ is just a workaround ? If so, for what ? To people wondering what this is all about, Stroustrup is speaks of C++ 'workarounds' only, not about the tools other languages offer. C++ is an organically grown construct of those 'workarounds', of which some change semantics based on context, and that makes it so easy for newcomers to write bad code, just out of convenience.

Anyway, we're stuck with it. Though I'd suggest to prepare to learn and get comfortable with another truly portable language that makes it easier for people to write better code. Am thinking of Rust.

(Disclaimer: I am just a hobbyist)

I have used multiple inheritance and it is useful, but also easy to shoot yourself in the foot. Though this is mainly because C++ didn't design it particularly well, but it's fine if used carefully.

Honestly, I like interfaces much better, as you can do in C#. In this case you are not defining a class per se, but an API for communication. Which makes more sense conceptually.

Classes that are related in some way, but not the same thing, can implement a common interface and be used together, though still not represent the same type of object. Maybe it is all semantics, but this makes sense.

23 days later