Interfaces vs. abstract classes

Sigh … some people just don’t get it…. 😛

Interfaces rock! Below is my comment from stackoverflow.com, a question about how to handle the “interfaces v. abstract classes” interview question in an interview.

  1. First, the “only one super class” answer is lame. Anyone who gave me that answer in an interview would be quickly countered with “C++ existed before Java and C++ had multiple super classes. Why do you think James Gosling only allowed one superclass for Java?”

    Understand the philosophy behind your answer otherwise you are toast (at least if I interview you.)

  2. Second, interfaces have multiple advantages over abstract classes, especially when designing interaction points between modules (i.e. the Facade pattern). The biggest one is not having a particular class structure imposed on the caller of a method. There is nothing worse than trying to use a method call that demands a particular class structure. It is painful and awkward. Using an interface *anything* can be passed to the method with a minimum of expectations.

    Example:

    public void foo(java.util.Hashtable bar); // Hashtable is concrete class

    vs.

    public void foo(java.util.Map bar); // Map is an interface

    For the former, the caller will always be taking their existing data structure and slamming it into a new Hashtable.

  3. Third, interfaces allow public methods in the concrete class implementers to be “private”. If the method is not declared in the interface then the method cannot be used (or misused) by classes that have no business using the method. Which brings me to point 4….
  4. Fourth, Interfaces represent a minimal contract between the implementing class and the caller. This minimal contract specifies exactly *how* the concrete implementer expects to be used and no more. The calling class is not allowed to use any other method not specified by the contract specified by interface. The interface name also flavors the developer’s expectation of how they should be using the interface implementor in the current context. If a developer is passed a

    public interface FragmentVisitor {
    public void visit(Node node);
    }

    The developer knows that the only method available is the visit method. They don’t get distracted by the bright shiny methods in the actual implementor’s concrete class.

  5. Lastly, abstract classes have many methods that are really only present for the subclasses to be using. Abstract classes tend to look a little like a mess to the outside developer, there is no guidance on which methods are intended to be used by outside code.

    Yes of course some such methods can be made protected. However, protected methods are also visible to other classes in the same package. And if the concrete class implements other interfaces, those methods must be public – even if those methods should not be called in the current method. This problem goes away with a narrowly defined interface that hides all implementation details and only exposes the allowed methods defined in the interface.

If the developer uses some “special” knowledge to cast an object to another broader interface or the concrete class itself, such a cast violates the expected contract, and the developer should be slapped with a salmon.

This entry was posted in code review, technical. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *