Do you need all 3 of them to have a class? In my experience classes are data+ methods that manipulate that data. Like a Vector class would have a rotate,normalize etc methods that return a new Vector.
That's a question of definition. There are many who will passionately insist that yes, you absolutely need all of them. I hypothesize but can't prove that these are people simply regurgitating what they were taught in a classroom and who have not yet left Java/C++ to see what else is out there and what else can work. It is perfectly feasible to be educated that way and then spend your entire career in Java or C++ and come to conceptualize everything else as "that crazy minority stuff that isn't like Real Programming", and, in their defense, they are at least correct about the "minority" part. It's easy to forget if you read HN a lot, but inheritance + polymorphism + encapsulation remain the massively dominant paradigm, especially if you assume most C# is still basically written that way despite supporting other paradigms.
Personally I take the loosest possibly view, mostly just "associating data and methods to operate on that data fairly tightly together, where they all get passed around as a unit". Some ability to have "x.y()" result in multiple possible implementations of "y" is necessary, or you just have a weird way of spelling function calls. That's about all I'll require to call something "OO" nowadays.
I think the number of developers that when starting a project start creating some inheritance tree is large. Some concepts work fit inheritance very well like GUI widgets or game entities, you would make a disservice not to tell students about the concepts and have them re-invent them.
Not sure how other languages do it, but in my daily work the only time I use inheritance is with an ORM , to get the magic to work you need to extend the base Model class , add a few lines of configuration code and you are done, for more advanced uses I think you have to override some methods.
But except the ORM code I don't think I used inheritance in a long time, though I used interfaces in some other cases.
Game entities really don't fit inheritance very well though! Even if using an OO approach it's far more flexible to compose. Otherwise it suffers from the classic large inheritance tree issues of lots of state and functionality leaking up the tree to common base classes. As an example the Unreal Engine used to have a heinously enormous base class called Actor. Another is that all the game entities in EVE Online actually bring the AI code with them. You can make it work but it's in spite of rather than because of inheritance. Anyone teaching students it's useful is doing them a great disservice.
I don't have experience with game engines, but I worked with Qt, WinForms, Flex4, Swing GUI libraries, and it made sense. All components inherit from a base widget, This base widget has everything you need, layout, positioning, mouse and keyboard events, painting. If you want to make a custom button that say is rotating when you click it you extend the Button and not start from scratch like you do in html. In html you see many custom components created from nested DIVs, this custom widgets are missing many basic features like accessibility and keyboard shortcuts and are broken for edge cases. As an example PayPal has a money amount text input but the Delete key does not work on it.
Could there be some insane case where the OOP of the GUIO widget is problematic, maybe , like when you want your app to have a window in the shape of a circle ... but I think is fair you get easy to use library for 99% of the cases and for 1% of the cases you might have to get your hands dirty and go outside the standard ways and maybe look under the hood.
Yeah GUIs seem to end up fitting reasonably well. They tend to be fairly modelled as specialisations. The problem with games is that it feels like they should but aren’t.
Maybe the issue is that the engine game evolves, new requirements are added and maybe a developer has a bad day and some ugly code is created.
If we consider a game like Minecraft, I would use something like a base class for blocks and a different base class for mobs, then if you add a new feature you put it in base class and all the objects will get it for free. I am not sure how Minecraft is architected but I loved how all entities including the player are the same, if you can do something to a player(push, drawn, burn, catapult, activate circuits , etc) all mobs would work the same.
I think GUIs work well because is a very well known and studied problem where with game engines you have a generic problem and then each game is bending the engine to try to use it for different type of games that the engine author did not consider at the beginning.
My conclusion is that some OOP is a tool you can use, you should not avoid it because a dude in a blog said so,the same with GOTO - I think I only used GOTO once , it was more efficient and more readable to use goto there then trying to workaround using it by creating variables and then adding checks (the problem was to efficiently break from inside 2 or more nested loops efficiently)
I think we need to separate inheritance trees (arbitrary depth of inheritance) from mixin/trait inheritance which has height = 2. The latter is a lot more useful in eg. games where objects are assembled from mixins like Legos. The former leads to fragility, class bloat and other problems (remember MFC...).
Basically, GUI frameworks are the only area I know where OOP - real, authentic long inheritance chains with encapsulation and extensibility - has worked well.
Exactly. Clusters of parameters and functions that manipulate those parameters all specific to a 'domian' is really what a class is for. Inheritance/ Polymorphism is just more machinery to do that with.
Functionality like mapping the keys to new names or uppercasing certain specific values or sending the data to certain places.
You could have the functions and parameters all in one long piece of code, or you could put them into domains which makes dealing with it, reading it, understanding it, and working with it easier, in my opinion.
Nope, that's not a class, that's a struct and a module with functions. Any method called as obj.foo(5) is really just a function foo with a hidden argument foo(obj, 5). Rust makes this architecture explicit with its structs and trait impls separated - and no OOP in sight.
Classes, on the other hand, are not structs with functions. More like black boxes whose contents can be swapped out at any moment. OOP is about hiding implementation and infinite extensibility.
I do not know Rust but this seems an implementation detail, like if I would make the Vector.normalize function static and then pass the this as an argument. Sometimes this pattern with static function works well too. My classes also have private methods and sometimes even private static pure functions. Anyway you Rust people do whatever you want and call them whatever you want , I will call a struct with methods a class.
Personally I take the loosest possibly view, mostly just "associating data and methods to operate on that data fairly tightly together, where they all get passed around as a unit". Some ability to have "x.y()" result in multiple possible implementations of "y" is necessary, or you just have a weird way of spelling function calls. That's about all I'll require to call something "OO" nowadays.