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.

Good day!

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?"

Thank you in advance.

share|improve this question
3  
duplicate of programmers.stackexchange.com/questions/65179/… –  Steven A. Lowe May 10 '11 at 14:27
    
Problem is you can only extend one class. –  user1249 Sep 16 '12 at 16:04
add comment

7 Answers

As many other programmers in this thread have stated, if you're using inheritance to achieve code-reuse, in such a fashion that you're not creating a relationship, but rather just saving yourself typing and work, then you're probably doing it wrong -- but that's from a software engineers perspective.

If you're using inheritance to create a "is a" relationship, then you're doing it the right way, for example:

 public abstract class Human {
      private int itsAge = 0;
      private int itsWeight = 0;

      public Human(int itsAge, int itsWeight) {
          setItsAge(itsAge);
          setItsWeight(itsWeight);
      }

      public setItsAge(int itsAge) {
          this.itsAge = itsAge;
      }

      public setItsWeight(int itsWeight) {
          this.itsWeight = itsWeight);
      }
 }

 public class Woman extends Human {
      public boolean isBeautiful = True;
      public Woman() { super(25, 125); } 
 }

If you're using inheritance to create a "has a" relationship, then you're talking about composition, for example:

// Continuation of the code above. 
public class Woman extends Human { 
     public boolean isBeautiful = True;
     public NiceRack niceRack = new NiceRack(34D);
     //... bla bla bla
}

In this case, you can see composition, because you can say that the Woman class, "has a" NiceRack.

If you're using inheritance to code to a contract and enforce a kind of behavior, then you're talking about using interfaces. (I love interfaces).

public interface ISexyTimeable {
    boolean sexyTime(ISexyTimeable someoneElse);
}
public class Woman extends Human implements ISexyTimeable {
    public boolean isBeautiful = True;
    public NiceRack niceRack = new NiceRack("34D");
    //... bla bla bla
    public boolean sexyTime(ISexyTimeable someoneElse) {
        return true;
        // This implementation is arbitrary, all we can go on
        // is that, according to the interface ISexyTimeable, 
        // this class, in order to implement the interface, 
        // must have a sexyTime() method that takes another
        // ISexyTimeable object as a parameter and returns a
        // boolean. 
        // In this case, sexyTime will always return true;
    }
}

On the other hand, doing the following is a really bad idea:

public class someSetOfUtilityMethods {
     private someSetOfUtilityMethods() {}
     public void someLongUtilityMethodThatDoesALotOfStuffIDontWantToType() {
     }
}

public class A extends someSetOfUtilityMethods {
    public void b() {
       super.someLong....IDontWantToType();
    }
}

Get it?

In my opinion, learning to use Utility classes is a great way to learn about encapsulation. I make it a habit, in each of my projects, to create a blank static class file (that I usually have set as a class library) to store utility methods in. And I call them from around the project.

(I know this is probably going to get deleted, but I wanted the poster to see it before it was, just because, sexual innuendos are so much easier to remember.)

share|improve this answer
add comment

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.

share|improve this answer
    
One nitpicking: the Circle-ellipse problem will still occur even if only pure interfaces are used, if the objects are to be mutable. –  rwong May 11 '11 at 7:06
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
2  
"you can only extend 1 class but implement many interfaces" That's true for Java as well as C#. –  FrustratedWithFormsDesigner May 10 '11 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 May 10 '11 at 18:41
add comment

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 say 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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
    
why the downvote? –  Mahmoud Hossam May 10 '11 at 19:04
3  
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 May 11 '11 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. –  Mahmoud Hossam May 11 '11 at 15:00
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.