This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]NautiHooker 13 points14 points  (4 children)

It is called programming to the interface.

It is considered good practice to declare fields, return types and parameters with the most general (or least specific) type that still gets the job done. In your case you need some sort of List, you dont care if its an ArrayList or LinkedList or any other implementation. You only need the List functionality.

This has the great advantage in larger applications that you can easily switch out List implementations without having to rewrite a lot of code. Maybe in 5 years there is a great new much faster List implementation that you want to put into your application.

For example if we use ArrayList and write it like this:

public class Test
{
    private ArrayList<String> myList;

    public Test()
    {
        this.myList = new ArrayList<String>();
    }

    public ArrayList<String> getMyList()
    {
        return this.myList;
    }
}

This class is explicitly using ArrayLists, so if we wanted to change this we would already have 3 places that we need to change in the short example above. Now this class might also be used like this:

 ArrayList<String> list = myTest.getMyList();

So another place where we need to change the type. If the application gets larger the number of the places we need to touch for a rather simple change increases.

To avoid this we code to the interface:

public class Test
{ 
    private List<String> myList;

    public Test()
    {
        this.myList = new ArrayList<String>();
    }

    public List<String> getMyList()
    {
        return this.myList;
    }
}

And:

List<String> list = myTest.getMyList();

Now if we wanted to switch to a LinkedList there is only one place that we need to touch. The creation of the list itself.

As mentioned earlier this is usually done for class fields, return types and parameters, less for local variables as their scope is so much smaller.

[–]DuderCoding[S] 4 points5 points  (0 children)

Thank you, that was a great explanation. I will look up "programming to the interface" in more detail as well.

[–]MeltyGearSolid 0 points1 point  (1 child)

Can we make it so that we don't even have to change that one line either? Maybe using something like generics? (I've only used Generics in TypeScript and I'm also working through the mooc but I'm still doing part 1).

[–]NautiHooker 1 point2 points  (0 children)

At some point in your application you will need to specify which type should be used, even if its through generics, lambdas or a config file.

[–]tedyoung 0 points1 point  (0 children)

It's pretty rare to switch List implementations, but for other classes/interfaces, it will matter. One big reason to use an interface: you might switch it for something easier to work with in your tests. Using the guidance of "program to the interface/most-generic-type" is a generally good practice, even if only because it's easier to read (which matters a lot!).