Interfaces exist solely to provide client classes with a means of treating unlike objects in a like manner.
Each interface adds a new type to a class.
Use an interface when you really need to support multiple inheritance.
Define an interface where heterogeneous classes are accessed as a single type. Approach the design of an interface from the client's perspective that wants to treat otherwise incompatible classes interchangeably. Consider where clients would need a single facility to operate across divergent classes and the name of that facility might be given an "-able" suffix (Cloneable, Serializable, Compressible, Drawable).
Interfaces are subject to a very important constraint - they are impossible to modify (even with pure additions) without breaking your clients.
An abstract class is a way to mix the definition of a class (with associated implementation) with the definition of an interfce (with its freedom from implementation).
Use an abstract class when more than one way to implement the abstraction is expected, then move common method implementations and attributes into the abstract class.
Use when the abstraction's interface is unstable.
All clients should couple themselves to the abstract class in their method parameters.
Clients should program to an interface, not a concrete class.
Clients shouldn't "name" concrete classes.
All parameters and return types should be defined as interface types (not class types). Use static factory methods to instantiate without "naming". A concrete object is created and returned as an interface type.
A factory method in the base class can evaluate the arguments that otherwise would be passed to many different constructors, create the correct concrete subclass, and return the object as a reference to the abstract base class.
Factory methods can have different or better names (than constructors do) to serve different purposes or document different results produced by the same list of parameter types [Color makeRGBcolor(r,g,b) and Color makeHSBcolor(h,s,b)]
Immutable classes can avoid object creation by providing factory methods that return objects from a class cache.
StringBuffer's toString() method is a factory method. When you call StringBuffer's toString(), the new String object shares the original StringBuffer's character array, until a StringBuffer call modifies the array.
In a GUI where real estate is limited, a set of check boxes might be appropriate when 3 or fewer choices need to be supported, and a scrollable list would be better for representing 4 or more choices. A factory could evaluate the array of choices specified by the user and create and return a customized subpanel.
In a computation where efficiency is dependent on the nature of the data, a factory could host the appropriate "intelligence". Example - an FFT uses four expansion equations of Euler's formula. In their general form, these equations require the computation of sines and cosines. But, in the case where "y" is zero, simple addition is the only computation. A factory method could test the value of "y" and create an "AddFFT" compute engine in the simple case, or, create a "TrigFFT" compute engine in the general case.
String has 9 constructors (that accept char array, byte array, String, and StringBuffer parameters) and 9 factory methods (that handle the rest of the primitive types). The factory methods may have unintuitive names like static String valueOf(char).
Some ideologues insist that all constructors should be private or protected. The only way to create instances of a class should be through factory methods. It's nobody's business but the class' whether a class manufactures a new object or recycles an old one.
James Cooper, "Using Design Patterns", Communications of the
ACM, June 1998, pp65-68
Mark Davis, "Abstraction", Java Report, June 99, pp80-89
Dirk Riehle and Erica Dubach, "Working with Java Interfaces and Classes, Java Report, July 99, pp35-46
Jim Waldo, "Dynamic Lingo", Performance Computing, July 98, pp25-29
Jim Waldo, "Between Classes and Interfaces", Unix Review, Apr 97, pp75-80
Jim Waldo, "Interface and Implementation", Unix Review, Dec 96, pp81-86
Jim Waldo, "Interface and Implementation, part 2", Unix Review, Feb 97, pp71-74
John Miller Crawford, "Interfaces - the outside story", Java Report, July 99, pp58-66