August 04, 2003"Inheritance considered evil" considered evilYou should always be very leery of any article that contains the words "considered evil" in its title. This article, where Allen Holub is unconvincingly trying to make a case that inheritance is evil, is no exception. There is a well-known phenomenon in the publishing industry pertaining to
sensationalism. Whenever you want to write something that will get the attention
of your readers, a simple technique is to pick a popular opinion and explain why
everyone is wrong about it. Base classes are considered fragile because you can modify a base class in a seemingly safe way, but this new behavior, when inherited by the derived classes, might cause the derived classes to malfunction. and then he proceeds to demonstrate something totally different. Ahem. What's overall disturbing with this article, and with the way Holub approaches problems in general, is the tendency to make sweeping statements. Allen demolishes inheritance by showing a very poor example of inheritance. Someone who would implement a Stack by
is clearly a beginner in object-oriented programming. Nothing that a good book won't fix. But no, instead of just observing this fact, Allen is trying to make a case that inheritance should be banned altogether. As I read through his articles, it's pretty clear to me that whatever he is trying to do, he is using the wrong language. How about Lisp instead? Some of his points are worth making, though, like the emphasis on interfaces. Now, there is a valid fight and it is important to raise every programmer's awareness to the importance of interface programming. We all know that inheritance can be abused, but isn't it so for every feature of every language on the planet? Instead of giving in to simple sensationalism, how about studying the pros and cons of inheritance and trying to educate your readers objectively? This kind of article would be understandable in a personal weblog, but I expect better from Javaworld. Posted by cedric at August 4, 2003 12:02 PMComments
Agreed -- you would hope that Holub's example is a straw man, one that only a beginner would write. But if you take a look at the actual JDK class java.util.Stack you'll see it extends Vector ... apparently it's not just beginners who overuse 'extends'? The biggest problem with this article is that it is five-ten years too late. Posted by: at August 4, 2003 04:10 PMThe problem with inheritance is that if your parents are unattractive, the same thing happens to you. Posted by: Jenny Schaffer at August 4, 2003 06:05 PMCedric-, Hristo Why do you even dignify such idiotic articles with a response? Posted by: Dave at August 6, 2003 07:18 AMI'm surprised how violent the reactions are to Holub's recommendations. Implementation inheritance has been known to be problematic, even back in pre-Java days (i.e. C++), good design was to avoid it. In C++ the distinction wasn't as obvious because there was no such things as interfaces. By convention you just avoided it. Let's just make it clear, implementation inheritance is convenient, the question be raised is it maintainable. However, delegation would work just as well and in fact be more flexible (i.e. dynamic inheritance). Finally, Holub's article is a preview of his book. So its pedagogical nature should be expected. Ouch. Sometimes it scares me how easily programmers can confuse common knowledge. This is one of those times. The pattern goes like this. Someone takes a readily understood and accepted concept, removes it from its original context, confuses it thoroughly, gives different meaning to it, and then proceeded to extoll the virtues of the new found wisdom as though it were something other than misplaced enthusiasm. Every language deals with inheritance in a different way. To examine the two mentioned above; Java uses single inheritance, public/private/protected access, abstract classes and interfaces as language constructs, but lacks a mechanism for composition via inheritance. C++ provides multiple inheritance, public/private/protected access, abstract classes and interfaces (via pure virtual methods), but also provides for composition via inheritance and even virtual inheritance. C++ can also alter the access of a class at composition via inheritance using public/private/protected. In some cases these features are similar and in others they are vastly different. The way C++ uses inheritance is not the same as the way Java uses inheritance. In C++ it actually makes a lot more sense to do composition via inheritance, so inheriting implementation and behaviour is far more common. In fact, that is the essential point. The issue at stake is not wether inheritance is good or bad, but wether you want to create a heirarchy of classes which share a common behaviour, or simply a common interface. The reason why most API's implement a Stack as a subclass of List is becuase it makes perfect sense to share the behaviour. To misunderstand this is to misunderstand object oriented programming. Clarifying what you want and understanding the concepts of type, composition, behaviour, interitance, polymorphism, and deligation are key to object oriented programming. These constructs have not been arrived at without reason or purpose. Stating that implementation inheritance is bad and should be avioded altogether simly shows that you have not understood the issues at hand. There is no one size fits all solution. Posted by: emerson at October 26, 2004 02:06 AMHello Cedric, In any case, I am a fervent believer that concrete inheritance is in fact, an implicit software requirement defect. The digressive reasoning behind this is extremely verbose, so I won't bore you today. Not to suggest that I refuse to use it, since for example, the Java language forces me to use it, but using this basis, I can make an informed decision and apply an optimal workaround. I've started work on a programming language that removes all the constructs of Java that imply requirement defect (admittedly, it's stalled at the moment), implements a complete API Specification as an example, and compiles to any bytecode representation (since that is left unspecified). I hope this example will be enough to convince even the most ignorant developers. http://www.jtiger.org/articles/why-extends-is-not-evil.html Posted by: Tony Morris at September 10, 2005 03:43 AM我公司是一家装专门提供集团电话批发、零售、安装、调试、维护、维修的专业设备供应商和服务商。http://oavip.net Posted by: 程控交换机 at December 21, 2006 12:56 AMOk, so... can somebody please tell me when should I use and when should I not use inheritance? Posted by: Narcélio Filho at July 16, 2007 08:35 PMLike any other feature -- use inheritance when you cannot do it any other way without repeating yourself. It's the principle of "least power". Combine that with solving problems by adding layers of indirection, and you end up with a reasonable balance. Don't write a class if a function will do. The key question with inheritance is substitution: "can this thing X also be considered a Y?". Someone who makes a class for a man driving a car called man_car, inheriting from both, has not understood. There is no such thing that is simultaneously a man and a car. (ok, maybe a rickshaw). This doesn't mean not to do abstraction. Abstraction is very important. But not everything is worthy of an abstraction. Pick the ones that matter and do them well. If you use complex technologies too soon, you'll trip over things like diamond inheritance when it was avoidable. Posted by: matthewinrandwick at August 1, 2007 10:41 PMPost a comment
|