Question

A cut code from effective java, here we used a List to obey the good practice of referring to objects by their interface.

// Good - uses interface as type
List<Subscriber> subscribers = new Vector<Subscriber>();

Assuming we had a car interface and 2wheel and 4wheel were concrete subclasses. Is it even recommended ( seems quite a yes ) to construct a list of type "car" ?

List<Car> car = new Vector<2wheel>();

instead of

List<2wheel> car = new Vector<2wheel>();
Was it helpful?

Solution

I agree with the book. Always use the interface type when possible. The only way I would use the 2wheel or 4wheel implementations in the List is if they contained specific methods that needed to be called that were not on the interface.

For example:

public interface Car{
   public void drive();
}

public class 2wheel implements Car{
   public void drive(){
      //implementation
   }
}


public class 4wheel implements Car{
   public void drive(){
      //implementation
   }

   public void initiate4WheelDrive(){
      //implementation
   }
}

If you had a List and the code using the list needed to call the initiate4WheelDrive method, then you must use the concrete implementation. This will often be determined by the calling code, but if possible stick to the interface so you can easily swap the implementation.

Another note, the name 2wheel would be an invalid name in Java since class and interface names cannot start with a number.

OTHER TIPS

An interface specificies a type, and many classes can share a similar (or identical) behavior by sharing the same type.

In cases where the interface represents the major functionality, purpose, or behavior of an implementing class it does make good sense to refer to instances of the type by using the interface name. The collection classes and the JDBC RowSet classes are great examples of this. A strongly defining characteristic of a CachedRowSet instance is that it is a RowSet, as defined by the contract of the RowSet interface.

But there are classes for which the interfaces they implement provide accessory functionality or behavior. The contract of the interface in these cases are not the raison d'etre of the class ... and here I disagree with Mr. Bloch's maxxim that every interface should become the type you refer to all instances by.

To make this more concrete, how many times are classes that implement Comparable instantiated as Comparables? Or Cloneables? Sure, it does sometimes make sense to use these "lesser interfaces" as types for certain method parameters ... but that is different than "always referring to objects as instances of a type defined by an interface."

TL;DR: the rule that interfaces should alwyas be used as object types is a good rule mostly when the interface has a well explicated contract and when the contract defines a major function, behavior, or purpose of the implementing class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top