Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

As far as I have understood(?), the "Extends is evil" idea is in direct opposition to the Open Closed Principle?

In here, the concept of OCP is presented as inherently using Extends:
http://www.oodesign.com/open-close-principle.html

While in for example this article, the act of extending is considered a capital offense?
http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html?page=1

What is the correct way to satisfy both OCP and not using Extends? Consider a simple BulletinBoard class that has Posts, which can be either NewsPosts or GuestbookPosts with different properties, but same methods/behaviour.

share|improve this question
2  
Don't believe everything you read. When you read "xxx is evil" in a programming context, remind yourself that xxx is probably not evil and question everything else in the article. At the very least, a more nuanced understanding of xxx is required. (Exception: if xxx = "singletons", disregard the preceding comment.) –  Caleb Sep 4 '13 at 13:52
1  
@Caleb, I was with you until the end. Now I question everything else you said :) –  ConditionRacer Sep 6 '13 at 15:51
1  
@Justin984 You have to draw the line somewhere. ;-) –  Caleb Sep 6 '13 at 16:48
add comment

4 Answers

up vote 10 down vote accepted

No, it is not.

Open-closed principle calls for encapsulating functionality in the classes. It does not say whether the interface should be defined by base class or interface.

"extends is evil" tells you to prefer implementing interfaces over extending base classes.

Since open-closed principle is fine with either, they are not opposed.

As for the "extends is evil", there are several reasons for which inheritance is used and Java does not let you distinguish them (C++ has protected and private inheritance that helps here):

  1. Implementing common interface for other code to use.
  2. Reusing base functionality.
  3. Specializing behaviour of mostly generic class.

You should use interfaces for the first so you don't tie yourself into single inheritance hierarchy. That's the main message of "extends is evil".

For the second the preferred method is composition, again so you don't tie yourself to single inheritance hierarchy.

But for the thirds, extending (abstract) base class is appropriate. Your example falls in the third case.

Note however, that the abstract base class should probably still implement an interface and the code should use it whenever it does not need the particular base class, which is most of the time.

Note:

evil, adj.: Something you should avoid most of the time, but not something you should avoid all the time. For example, you will end up using these "evil" things whenever they are "the least evil of the evil alternatives." (C++ FAQ)

That applies in all similar cases where somebody calls some technique "evil". It does not mean you must not use it, ever. Just points out there is a preferred alternative.

share|improve this answer
add comment

The first link actually uses the strategy pattern (abstract method with implementation in each Shape subclass), so there's nothing evil going on there, because as the author says, you don't have to modify the GraphicEditor to support new shapes. Keep in mind though, that in that example, you are interested in a shared, common interface (the draw() method). You can obtain that by using an abstract method and inheritance, but you could achieve the same thing with regular interfaces.
OCP and extends are not per definition orthogonal to each other; it's just that a lot of people instinctively resort to inheritance for common properties, not for common behaviour. This can often lead to all sorts of mangled spaghetti code.
As per your example: you're not talking about behaviour, only about properties, so the question is: what kind of logic is there, and where, that would differ based upon the type of Post?

share|improve this answer
    
The Post types would all share common behaviour: to display a template that uses the properties associated with the given type of Post. –  Juha Untinen Sep 4 '13 at 11:22
    
That sounds the same as the shapes example you referenced. –  Stefan Billiet Sep 4 '13 at 11:28
    
Indeed. Therefore the question about the validity of the pattern, as I had mostly been wary of using Extends due to reading the "Extends is evil" article much before I had learned more about SOLID :) –  Juha Untinen Sep 4 '13 at 11:36
add comment

Well, my 2c is, following Joshua Bloch's guide lines as written in his book Effective Java:

Prefer Interfaces To Abstract Classes (it's the title of the 4.18 Chapter in that book's 2nd edition)

The key word here is "Prefer" in the same way that the principles you quote are principles and not laws. They are guide lines, to be used more often than not, but to always take into consideration if the current situation really is pertinent to a given principle or another.

More to the point, yes "extends" is evil, we should use interfaces to declare base types. How ever the point made in the book I quote (and which I personally like a lot) is that given an interface, you do get benefits from making some abstract implementations of it as helper classes for the extension of that interface. Imagine you make a Shape interface, which, amongst others, has a "setColor(Color)" method. If you know that in the context in which your interface will be used (by either you or somebody else), there's a big chance that most of the shapes will be black, you can make an abstract class called BlackShape (implements Shape) which asigns Black to the shape's color right from the start, and only leaves other methods as abstract. The important thing in such a case is to properlly document the fact that the Shape interface should be the base of any concrete Shape implementation in general, and only those who need black shapes should use the BlackShape abstract class if they so prefer. This way you ensure that noone will inadvertently think that BlackShape is the base of all shapes, and you'll avoid Liskov Substitution Principle-like violations (for example) where a Red Shape is created by extending the BlackShape class and overriding the setColor(Color) method.

share|improve this answer
add comment

Inheritance is one of the features a language has to have in order to be considered object oriented.

In some languages the the verb to extend is used to refer the action of inheritance.

Saying "extends is evil" is equivalent to saying "inheritance is evil".

Since inheritance is something object oriented languages do, then "OOP is evil", which is frankly nonsensical.

This logic exercise is called "reductio ad absurdum" (reduction to absurdity).

If someone tells you the earth is flat, ask them to walk with you until you find the edge.

I will add my own nonsense to the stack: people who say "extends is evil" are evil.

share|improve this answer
    
-1: In the sense of this definition extends is indeed evil. With that definition and because it explicitly speaks of extends as opposed to implements, the following logical exercise does not stand. –  Jan Hudec Sep 5 '13 at 11:14
    
I only new this definition: merriam-webster.com/dictionary/evil –  user61852 Sep 5 '13 at 16:37
    
Yes, that's the normal definition. But people grossly exaggerate when they say that, so the other definition. –  Jan Hudec Sep 6 '13 at 6:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.