39

Jame Gosling said

“You should avoid implementation inheritance whenever possible.”

and instead, use interface inheritance.

But why? How can we avoid inheriting the structure of an object using the keyword "extends", and at the same time make our code Object Oriented?

Could someone please give an Object Oriented example illustrating this concept in a scenario like "ordering a book in a bookstore?"

2

6 Answers 6

39

Gosling did not say to avoid the use of extends keyword... he just said to not use inheritance as a means to achieve code re-use.

Inheritance is not bad per se and is a very powerful (essential) tool to use in creating OO structures. However when not used properly (that is when used for something else than creating Object structures) it creates code that is very tightly coupled and very hard to maintain.

Because inheritance should be used for creating polymorphic structures it can be done just as easily with interfaces, hence the statement to use interfaces rather than classes when designing your Object Structures. If you find yourself using extends as a means to avoid copy-pasting code from one object to another perhaps you are using it wrong and would be better served with a specialized class to handle this functionality and share that code through composition instead.

Read about the Liskov Substitution Principle and understand it. Whenever you are about to extend a class ( or an interface for that matter) ask yourself if you are violating the principle, if yes then you are most likely (ab)using inheritance in unnatural ways. It is easy to do and often seems like the right thing but it will make your code more difficult to maintain, test and evolve.

--- Edit This answer makes a pretty good argument to answer the question in more general terms.

3
  • 3
    (Implementation) inheritance is not essential for creating OO structures. You can have an OO language without it.
    – Andres F.
    Commented Feb 11, 2016 at 12:45
  • Could you provide an example ? I've never seen OO without inheritance.
    – Newtopian
    Commented Feb 15, 2016 at 14:23
  • 1
    The problem is that there is no accepted definition of what OOP is. (As an aside, even Alan Kay came to regret the common interpretation of his definition, with its current emphasis on "objects" instead of "messages"). Here is an attempt at an answer to your question. I do agree it's uncommon to see OOP without inheritance; hence my argument was merely that it isn't essential ;)
    – Andres F.
    Commented Feb 15, 2016 at 14:28
9

In the early days of object-oriented programming, implementation inheritance was the golden hammer of code re-use. If there was a piece of functionality in some class that you needed, the thing to do was to publicly inherit from that class (these were the days when C++ was more prevalent than Java), and you got that functionality "for free."

Except, it wasn't really free. The result was extremely convoluted inheritance hierarchies that were nearly impossible to understand, including diamond-shaped inheritance trees that were difficult to handle. This is part of the reason the designers of Java opted not to support multiple inheritance of classes.

Gosling's advice (and other statements) like it were strong medicine for a fairly serious disease, and it's possible some babies got thrown out with the bathwater. There's nothing wrong with using inheritance to model a relationship between classes that truly is is-a. But if you're just looking to use a piece of functionality from another class, you'll be better off investigating other options first.

6

Inheritance has gathered quite the scary reputation lately. One reason to avoid it goes along with the design principle of "composition over inheritance", which basically encourages people to not use inheritance where that is not the true relationship, just to save some code writing. This sort of inheritance can cause some hard to find and hard to fix bugs. The reason your friend was probably suggesting to use an interface instead is because interfaces provide a more flexible and maintainable solution to distributed api's. They more often allow changes to be made to an api without breaking user's code, where exposing classes often does break user's code. The best example of this in .Net is the difference of use between List and IList.

5

Because you can only extend one class, while you can implement many interfaces.

I once heard that inheritance defines what you are, but interfaces define a role you can play.

Interfaces also allow for a better use of polymorphism.

That might be part of the reason.

3
  • why the downvote? Commented May 10, 2011 at 19:04
  • 7
    The answer puts the cart before the horse. Java only allows you to extend one class because of the priniciple Gosling (designer of Java) articulated. It's like saying kids should wear helmets while riding bicycles because that's the law. That's true, but both the law and the advice stem from avoidance of head injuries.
    – JohnMcG
    Commented May 11, 2011 at 14:44
  • @JohnMcG I'm not explaining the design choice Gosling made, I'm merely giving advice to a coder, coders usually don't bother with language design. Commented May 11, 2011 at 15:00
1

I have been taught this too and I do prefer interfaces where possible (of course I still use inheritance where is make sense).

One thing I think it does is decouple your code from specific implementations. Say I have a class called ConsoleWriter and that gets passed into a method to write something out and it writes it to the console. Now lets say I want to switch to printing out to a GUI window. Well now I have to either modify the method or write a new one that take GUIWriter as a parameter. If I started by defining a IWriter interface and had the method take in an IWriter I could start with the ConsoleWriter (which would implement the IWriter interface) and then later write a new class called GUIWriter (which also implements the IWriter interface) and then I would just have to switch out the class being passed.

Another thing (which is true for C#, not sure about Java) is that you can only extend 1 class but implement many interfaces. Lets say I had a classes named Teacher, MathTeacher, and HistoryTeacher. Now MathTeacher and HistoryTeacher extend from Teacher but what if we want a class that represent someone who is both a MathTeacher and HistoryTeacher. It can get pretty messy when try to inherit from multiple classes when you can only do it one at a time (there are way but they are not exactly optimal). With interfaces you can have 2 interfaces called IMathTeacher and IHistoryTeacher and then have one class that extend from Teacher and implement those 2 interfaces.

One downside that with using interfaces is that sometimes I see people duplicate code (since you have to create the implementation for each class the implement the interface) however there a clean solution to this problem, for example the use of things like delegates (not sure what the Java equivalent to that is).

The think the biggest reason to use interfaces over inheritances is the decoupling of implementation code but don't think that inheritance is evil as it is still very useful.

2
  • 2
    "you can only extend 1 class but implement many interfaces" That's true for Java as well as C#. Commented May 10, 2011 at 14:51
  • One possible solution to the code duplication problem is to create an abstract class that implements the interface and extend that. Use with care, though; there's only a few cases I've seen that it makes sense.
    – Michael K
    Commented May 10, 2011 at 18:41
0

If you inherit from a class, you take a dependency not only on that class but you also have to honor whatever implicit contracts have been created by clients of that class. Uncle Bob provides a great example of how it's easy to subtlely violate the Liskov Substitution Principle using the basic Square extends Rectangle dilemma. Interfaces, since they have no implementation also have no hidden contracts.

1
  • 3
    One nitpicking: the Circle-ellipse problem will still occur even if only pure interfaces are used, if the objects are to be mutable.
    – rwong
    Commented May 11, 2011 at 7:06

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.