Programming to Interfaces in Java

Seasoned Java programmers are programming to interfaces. What does it means?

Let’s consider a simple example. Let’s say I’ve declared a variable customers of type ArrayList:

ArrayList<Customer> customers = new ArrayList<>(3);

While this code is correct,  there a better way of declaring the variable customers:

List<Customer> customers = new ArrayList(3);

You can read the first example as follows: “I want to declare a variable customers that will have all access to all API offered by the class ArrayList“. The second version means the following: “I want to declare a variable customers that has a behavior declared in the List interface”. The first example declares a variable of a specific implementation of the List interface – ArrayList. Now rake a look at this code example:

ArrayList<Customer> customers = new ArrayList<>(3);

// The code to populate customers with instances of 
// Customer is omitted for brevity

int totalElem = customers.size();

// Iterate through the list customers and do something with each
// element of this collection

for (int i=0; i<totalElem;i++){
    Customer currentCustomer= customers.get(i);
    System.out.println(currentCustomer);
  }
}

ArrayList implements several interfaces besides List, which means that it has more methods that the List defines.  But if you read the documentation on the List interface, you’ll see that among others it includes the methods as add(), get(), and size() , which are the only ones used with our collection customers. If this is all we need, declaring a variable customers of type List gives us more flexibility. If later we decide to switch to a different implementation of the List (e.g. LinkedList instead of ArrayList ) we won’t need to change the type of the variable customers.

You may say that changing a variable declaration from ArrayList to LinkedList it’s not a big deal – it’s still the same line of code. But it may be a bigger deal if, say you program needs to pass the object referred by customers to another object’s method that also was declared with the argument of type ArrayList:

processCustomers (ArrayList<Customer> customers){

...
}

Now we need to change both the variable and the method argument declarations . In large projects such a refactoring may become a time consuming process.

If you just need a behavior defined in a particular interface (e.g. List), declare the variable of this interface type rather than of a concrete implementation (e.g. ArrayList) of this interface.

P.S. Here’s the Java 8 way of writing the above loop, which is not relevant for the blog subject:

customers.forEach( customer -> System.out.println(customer));
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s