4 ms·
Well, if what you are doing is inheritance-heavy, then OOP features will make your code cleaner. It's what OOP is made for. You can do it in Go, but it's not as
by tormeh 12y ago
Well, if what you are doing is inheritance-heavy, then OOP features will make your code cleaner. It's what OOP is made for. You can do it in Go, but it's not as elegant.
- NateDad 12y agoThere is almost never code that requires inheritance.
- jrockway 12y agoInheritance, in practice, is cut-n-paste for people that think they're too smart for cut-n-paste. "Give me an object like Foo, but with this one little thing changed."
- xienze 12y agoSure, you can clone Foo into Bar and change one thing in Bar. But what happens when you need to change functionality common between Foo and Bar? Oh right, you have to change the same thing in two places now. Doesn't seem so smart anymore...
- NateDad 12y agoThis is why Go has standalone functions and interfaces. You can easily share logic between types without having the types be the same thing. The biggest problem with inheritance is that it's a lot like monkey patching (except in production)... the rest of the base class's code expects method X to do ABC, and you've just swapped out the implementation to do LMNO ... and if that never bites you in the ass, you're luckier than most OO programmers I know.
- jrockway 12y agoThis is the big insight. Instead of trying to inherit code, figure out what that code does that interesting, and allow that code to do the interesting things without being inside the class. For example, imagine your class has a "WriteToFile" method. Instead of that, it should just have a method to return its representation, delegating the responsibility of writing to a file to something else. (Of course, the fact that a file can be written to should also be one of those "interesting things", and the thing that writes shouldn't care that it's backed by a file.) Instead of foo.WriteToFile("/tmp/foo") You might write: file.Write(foo.Representation()). I promise that most inheritance in the real world is attempting to reuse something like "WriteToFile". "I wouldn't want to copy-paste the file-writing code, so I'll inherit from something that can write itself to the file." No. Don't do that.
- spopejoy 12y agoMore than just "in practice", it might be worse than copy/paste. Richard Gabriel nailed it in the 90s when he identified inheritance as a form of compression, not reuse, forcing the programmer to have to understand every class under inheritance to understand any part of it: Compression is a little dangerous because it requires the programmer to understand a fair amount about the context from which compressed code will take its meaning. Not only does this require available source code or excellent documentation, but the nature of inherited language also forces the programmer to understand the source or documentation. If a programmer needs a lot of context to understand a program he needs to extend, he may make mistake because of misunderstandings. (from Patterns in Software, which is a really deep if long-winded book)
- dragonwriter 12y agoInheritance isn't a property of what code does, but how the programmer chooses to do it. There is no problem that is inherently inheritance-heavy.
- JulianMorrison 12y agoInheritance is almost always an anti-pattern. It's encapsulation-breaking, dependency-creating, brittle and limited.
- ajuc 12y agoInheritance as taught in OO courses (deep class hierarchies) is bad most of the time. We can save 100 lines of code there by coupling 2 slightly related things forever (and arbitrarily choosing this criteria for division as the most important). I've made game before I knew OO programming. I haven't knew it then, but I used Interpreter Pattern - there was data model, with a list of records, each record had some enums deciding how game logic should handle it. There was main loop updating the model using these enums to choose logic to run on this record. It wasn't pretty but it worked, I was able to modify it however I wanted, to choose logic to run on some record basing on enums, other atributes of given record, attributes of parent records, or of colliding records, on whatever I wanted basicaly. Then I rewrote the game to use OO design (I was enthusiastic- this is exactly what I need - I thought). It turns out that I had to choose arbitrary divisions. I can divide game objects into Solid and non-solid, Static and Movable, Visible and Invisible, and also Smart vs Dumb Objects. Which division should be first in class hierarchy? All the rest would need to be duplicated anyway. SmartMovableVisible, SmartMovableInvisible, SmartStaticVisible, etc... Ugly. Inheritance solves part of the problem and leaves you with inconsistent solution. The real solution is strategy pattern, and composition over inheritance. It can be done just as well in languages without inheritance (but with lambdas).
- vegedor 12y agoI don't agree with the premises. Teaching in higher classes assumes independent study of the reader as enhancement. For me it's making much more sense to look at a consistent implementation of OOP features in C [1] (understanding less and less to the end of the latest paper). It make sense to understand the data structures behind it to reason about the transformation of your game to OOP. For your problem there's Multiple Inheritance, but not every OOP-Language supports it. You have movable, visible, etc as objects and game_objects inherit from them as needed. If you have learned OOP with a toy metaphor and dived straight into Java or Python, you might miss out on some formal fundamentals. Some say Java doesn't implement OOP properly, but at least it's running ;). Naturally most students also want to get practical and don't want to dabble in the dire theory. In C you'd have bitmasks encoding the types and functions called based on that (or how'd you do it? gibe references). If you had your logic wired up to call functions straight away, it might have made sense to encode the functionality as member functions, to have an object being immobile simply by not using the move function. The data would be stored in pools of other objects, like location data, that your functions work on. I'm still learning. If I'm not making sense, tell me, but I think that's what MV* does? For a simple enough problem there are different probable solutions [1] http://ldeniau.web.cern.ch/ldeniau/oopc.html http://ldeniau.web.cern.ch/ldeniau/oopc.html but there are others as well