"Subclassing is not an end in and of itself, it's a technique which is occasionally handy. And I'll let you in on a little secret - I personally almost never use subclassing. It's not that I one day decided that subclassing is bad and that one should avoid it, it's that as I got better at coming up with simple designs I wound up using it less and less, until eventually I almost stopped using it entirely. Subclassing is, quite simply, awkward. Any design which uses subclassing should be treated with skepticism. Any design which requires subclassing across encapsulation boundaries should be assumed to be a disaster."
- Paul Buchheit
from Bookmarklet
I tend to agree, at least about the "subclassing is generally bad" part.
- Paul Buchheit
especially true in duck typed languages where you don't need subclassing for polymorphism
- Karl Rosaen
"Occasionally handy" sounds spot on to me. OO languages often lead people to overemphasize inheritance.
- Bruce Lewis
Subclassing seems to be necessary when you are using a library of third party components in a non-duck-typed language and you encounter requirements that one of your components doesn't support. Sucks when it happens, but what else are you supposed to do?
- Jason Wehmhoener
Meh. I disagree, but only provisionally. Subclassing examples are uniformly bad. Subclassing in practice tends to be bad because it's done either a) by newbs or b) by people who've not written lots of OOP, or c) by people who've never had to maintain anything. I've written plenty of good cases of subclasses, which turned out to be extremely handy. The problem with subclassing is that you tend to have to think way, way ahead to get it right. My favorite example is user management. Every good web application needs users. If you make him generic enough, then you can subclass him to provide different login methods quite easily. A user that authenticates via Facebook Connect, for example. Or via Twitter OAUTH. Or OpenID. Or Google. Or whatever. Different subclasses for the users make this easy to implement, as long as the generic user is there.
- Otto
I think one should be careful to separate sub-typing from subclassing, and interface inheritance vs implementation inheritance, and also virtual dispatch (C++/Java) vs multimethods vs Haskell-style typeclasses. Subclassing as a notion is too broad to apply a brush with all the cons. Implementation inheritance, for example, is usually used to save delegation boilerplate and allow 'hooks' where in a dynamic language, you'd just copy or mutate a method (Cat.speak = Animal.speak), whereas sub-typing interfaces is used to setup type constraints/bounds in many cases.
- Ray Cromwell
I noticed that implementation inheritance is explicitly excluded from noop: http://code.google.com/p/noop/. I do find it amusing that the language which might have actually had the "best" design for OO programing was Visual Basic..
- Nick Lothian
Otto, I would use "subclassing User objects based on login method" as a good example of misusing inheritance. What if Users vary in other ways, are you going to create subtypes of each one? The login method should not determine the type of user, but should probably be its own object (with a generic login interface perhaps).
- Paul Buchheit
I think standard OODA principles (which are rarely followed) would advise against putting responsibility for knowing how to log in on a User object. Login code must typically be privileged and depending on security mode (sandboxed vs capability based) you wouldn't necessarily want privileged code inside of user, which is likely an object that has many consumers.
- Ray Cromwell
As much as I generally avoid subclassing, the one place where I used it most effectively was a Shape class that I wrote for a vector drawing program. I didn't have a Square class, but you can be damn sure that Ellipse and Rectangle were closely related -- the only difference is the Paint() method! And why wouldn't RoundedRect be a subclass of Rectangle?
- Gabe
I don't do a lot of OO programming, but last year I was teaching a python for linguists class, and we did cover OO some. I used an example of a bird class, with a subclass for penguins, in which the fly() method was overwritten. Is this example just as bad as the rectangle and square? Do people agree with the comment that a subclass should have all the same properties as the parent class (specifically that width = height for a square, but not a rectangle)?
- Robert Felty
Rob, I tend to think that subclassing is good for when you want to describe an object that's just like some other object, just with a few differences. Why write a whole new Square class? Just take a Rectangle and override Height and Weight to make sure they're always the same.
- Gabe
If I were teaching beginners, I would just tell them to not use subclassing. People learning to program should focus on learning to program, not learning a set of language features.
- Paul Buchheit
Not to start with, but certainly before subclassing.
- Paul Buchheit
If you were teaching beginners, why would the word subclassing ever enter into their vocabulary?
- Gabe
I'd tell them to start with Structure and Interpretation of Computer Programs :)
- Ray Cromwell
But Ray, that book uses a weird language, Scheme. Would you use a web site written using Scheme?
- Bruce Lewis
^Is that even possible? LOL did Scheme in freshman year, hated it
- LANjackal
I'm still waiting for Ray's answer. If Scheme is such a good language for thinking about programming, would you use a web site written with it?
- Bruce Lewis
Scheme is a shit language to learn with IMO. I got most of my programming experience and learning via FORTRAN and MATLAB. Then again, I'm an engineer and number crunching is what I do, not building apps per se
- LANjackal
from IM
Article claims: "Taken literally, it would never make sense to make a full-blown class for such a trivial piece of functionality. There simply would be more lines of code taken up making declarations than could possibly be saved by convenience." That seems likely to be untrue if you have a program which uses a lot of Squares. So: the article's case seems pretty feeble.
- Tim Tyler
I like the book SICP not because of Lisp/Scheme, but because of the way it incrementally attacks programming problems. Truthfully, it can be taught using any language, although some are more concise than others, and stuff like C pointers and manual memory allocation obscure some algorithms.
- Ray Cromwell
Ray, I was trying to trick you into agreeing to use http://ourdoings.com/ but you didn't fall for it. Curses, foiled again.
- Bruce Lewis
Really, it's hard to imagine a better programming language for beginners than Python. In particular, Python programs do what it looks like they should do, and you don't have to waste time hunting for missing brackets or semicolons.
- Gabe
Paul, users are actually a good example because your users tend to not vary a lot from one to another in many ways. They always have the same fields, etc. Generally speaking, of course. Also, the login method is an important way to separate user types because different methods require different approaches to keep the user "logged in" sometimes, and also might require differing inputs for registration (a facebook connect won't give you the users actual email address, for example, so you have to ask them for that explicitly) and so forth.
- Otto
from iPhone
@Gabe BASIC, COBOL, and FORTRAN? :) I think human beings being very visual creatures, and visual feedback providing pleasing stimulus, some language deeply integrated with graphics is probably best for first language, ala turtle graphics or EToys.
- Ray Cromwell
Ray: Python is also good because it doesn't have arcane syntax (like COBOL and FORTRAN). I agree that BASIC is a great language for beginners, but it's just too old. If you modernized BASIC, I think you'd come up with something like Python.
- Gabe
MIT recently switched to Python for their into programming courses (I think from Scheme). I like "Think Python" as a nice introduction to programming. Best of all, the book is open source (written in LaTeX) http://www.greenteapress.com/thinkpy...
- Robert Felty
You can make a good case multiple inheritance is bad, but subclassing is such an integral part of OO languages like Java and C++ that I can't see any way you should avoid or discourage its use. You can argue when you should teach it to new programmers, but any experienced programmer developing any non trivial architecture or API should be making extensive use of it in the right places. Its a primary mechanism for code reuse, maintainability and consist behavior. Reference Cocoa, Android, Qt...
- Ed Millard
No one has mentioned Smalltalk/Squeak as a teaching language. These languages are very nice for teaching because of the way the runtime image is integrated with the IDE as a kind of persistent database. People can write code to tickle objects, inspect anything, and see immediate results. EToys is a classic example of what you can do.
- Ray Cromwell
I think a good amount of problems (with subclassing) comes from the packages/modules system and importing classes from other packages/modules creating on the long run messy dependencies between modules (and violating module isolation); I find Gilad Bracha's Newspeak an interesting take on this problem, you can read http://gbracha.blogspot.com/2007... , http://gbracha.blogspot.com/2007... and http://gbracha.blogspot.com/2009... , I found some concepts as "Newspeak won’t let you create a module with concrete external dependencies, because that wouldn’t really be a module, would it?" particularly refreshing.
- Marco Fabbri
Otto's example has a baked-in assumption that each user only has one login method, whereas (as FriendFeed shows) having multiple login methods for a given user is an advantage. If you subclass for login method, you make it very hard to support logging in the same user in different ways...
- Kevin Marks
tornado's auth example uses subclassing :) but actually, it looks like it's designed so, using multiple inheritance in python, you can mixin multiple auth types? http://github.com/faceboo... another reason why this issue isn't so cut and dry :)
- Karl Rosaen
Kevin: Not at all. You can have the same user with multiple login methods. That's the beauty of it. You're storing the login methodology separate from the underlying user in that manner. I've done this before, it works fine for any number of login methods, on all users. The one you instantiate is just which way they used to login that particular time. If they login differently, you instantiate them using the other class. Same user, different methods. That's the whole point of making the underlying user class more generic, specifically to support multiple login methods.
- Otto
actually, no, looks like tornado auth is intended to mix *one* auth mechanism in, but as Otto mentions, you could do this for the appropriate instance
- Karl Rosaen
The difference in creating Rectangle and Square classes vs creating methods to create square and rectangle in a polygon class is that in latter you do an Object Oriented Analysis first, rather than pushing your own limited knowledge of system requirements (like you think of a requirement for rectangles and squares but don't think about entire system) into design
- thequark