4 ms·
Inheritance may have some limited utility but it often degenerates into "spaghetti code" dressed up to appear modern and acceptable. Just like "goto" in the da
by jqpabc123 10mo ago
Inheritance may have some limited utility but it often degenerates into "spaghetti code" dressed up to appear modern and acceptable.
Just like "goto" in the days of old, it is best used sparingly.
- WCSTombs 10mo agoThere's a now well-known guideline that says "prefer composition over inheritance." When I saw that, it clarified a lot of things. While much of software design can theoretically be approached in terms of class hierarchies, that's rarely the right place to begin, since after you start preferring composition, inheritance is mostly just a tool to achieve polymorphism. It's a bit of a tangent, but I think the "class Dog extends Animal" type of tutorial did a lot of damage to impressionable programmers. Because it's completely abstract and basically meaningless, it's impossible to look at it critically and discuss why you would choose this or another approach, so the idea of class hierarchies just becomes a sort of dogma (so to speak).
- jqpabc123 10mo agodid a lot of damage to impressionable programmers. As they say, "Those who can do. Those who can't teach".
- tonyedgecombe 10mo agoI always disliked that phrase. In my experience one of the best ways to check whether you understand a subject fully is to teach a course on it.
- riffraff 10mo agoIIRC "Object Oriented Software Construction" by Bertrand Meyer makes it a point to argue against common inheritance examples (Rectangle < Shape, Employee < Person, etc), while still arguing for the utility of (multiple!) inheritance. It's an interesting, if dated, read.
- zamadatix 10mo agoI just went through a CSCI degree program after a long time in the field (figured I'd have some fun + try to catch a few things I may not have had a chance to mess with much over the years, like databases) and I gave myself a pretty decent lean on C++ programming courses where I could. The introduction to class inheritance started with the classic "Dog extends Animal" example. Honestly though, that was actually really good for new programmers in the course for exactly the reasons you point out: it's completely abstract and meaningless without immediately inviting urges of "well, why wouldn't I just do something like <x> instead" yet is also relatively straightforward way to learn "well, what the hell even IS class composition?" before you move on to the "more practical" examples where it can start to be better to dive into "well, when and why would I USE inheritance over something else?" type probing. The course actually did pretty good with both halves of that around the Dog/Animal example... and then it all fell off the rails a bit as inheritance was given far too much weight in the content of that and the following courses. I think even my last C++ final project still had using inheritance as a design requirement, and by that point the things the projects were about weren't really great fits for inheritance so you had to just shove it in anyways. To me it seems exactly like how implementing "uint32_t factorial(uint32_t x)" is a GOD AWFUL practical example of when to use recursion but a FANTASTIC way to introduce what a recursive function is, because that's exactly how you already learned about it in math classes. In the same way, once recursive functions are introduced with a basic understanding of what it is, it's good to move to more practical examples and poke at "why was that actually not a great way to implement factorial but it was great for traversing trees or..." type exploration/questioning.
- HelloNurse 10mo agoMeaningless toy examples have the problem that they can appear to make sense, planting the seeds of terrible ideas. If in a course example Dog extends Animal, it can be an arbitrary demonstration of language mechanisms (with an uncontroversial is-a relationship) but even in that case it is implicitly suggested that it is a good or "normal" design, implying an alarmingly complex program that has good reasons to deal with those two types. Such a program is usually not described for brevity, giving the false impression that it exists: if the problem were analyzed with any diligence, usually Dog would appear a completely pointless complication.
- llmslave2 10mo agoInheritance is great, just depends how you use it. I've never once reached for it for building servers. For games? All the time.
- echelon 10mo agoThe only two domains where I've felt inheritance is useful are video games and windowing systems. Inheritance is actually useful for Widget > Input > TextBox since methods and behaviors do follow parent-child and even sibling relationships. But there aren't many domains like this. Rust and other languages choosing traits and type classes instead of strict species-oriented class inheritance seems like the much more modern and more widely applicable approach. Classes feel clinical and dated.
- llmslave2 10mo agoAnything where you have literal "instances" of something with common state/behaviour is prime for inheritance, but that's different from trying to model a domain as a set of hierarchal objects. But I do like classes - you can use them without inheritance, and the other stuff that comes with them (encapsulation, polymorphism, etc) fits my mental model. [0] Classes are just syntactic sugar over closures at the end of the day. But inheritance is best when it's limited and shallow. 0: The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures." Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress. On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.
- bheadmaster 10mo agoInheritance is often used as an enabler for polymorphism in languages that don't support it in any other way. Somehow, it leaked out and convinced everyone that it is a good thing on its own.
- goatlover 10mo agoAlso encapsulation and code reuse. Message passing if you go by the guy who coined the term.
- bheadmaster 10mo agoEncapsulation is possible without inheritance. And "code reuse" is a vague concept that had nothing to do with inheritance in particular. Not even gonna comment on "message passing".
- rhdunn 10mo agoThere are two types of inheritance: - interface/API based -- this is supported in modern languages via interfaces, traits, etc. - implementation/code based -- modern languages tend to only support single inheritance; they tend to also support default method implementations on the interfaces/traits
- goatlover 10mo agoIt's interesting that Python does support multiple inheritance.
- bheadmaster 10mo ago> interfaces, traits, etc. Those are actually mechanisms for achieving polymorphism. Inheritence inherently (heh) consists of "inheriting" parent class' internals and having ability to extend them. It is basically composition, polymorphism and monkeypatching in a trench coat.
- atoav 10mo agoSo it is good that most Rusts introductions tell you that you should favor composition over inheritance in multiple places: https://rust-for-c-programmers.com/ch20/20_3_rust_s_approach_traits_composition_and_encapsulation.html#203-rusts-approach-traits-composition-and-encapsulation https://rust-for-c-programmers.com/ch20/20_3_rust_s_approach... If Rust pushes any concept it is the use of traits: https://rust-lang.github.io/book/ch10-02-traits.html https://rust-lang.github.io/book/ch10-02-traits.html