Так делается для того, чтобы оставить за собой возможность впоследствии поменять реализацию не меняя интерфейс. Например, в будущем может потребоваться заменить реализацию ArrayList на LinkedList, если бы в качестве типа переменной был указан конкретный класс, то к тому времени код мог бы уже обрасти различными обращениями к, специфическим для конкретного класса, методами, выходящими за границы интерфейса List. В таком случае при замене реализации на LinkedList пришлось бы выискивать в коде и выкорчевывать оттуда все обращения к специфике ArrayList. На сколько это адски сложная задача знают все, кому приходилось работать над крупными проектами. Поэтому люди, знакомые с этой проблемой, предпочитают предупреждать подобные проблемы заранее, то есть во всех местах, где возможна смена реализации в будущем (то есть почти везде), стараются пользоваться исключительно интерфейсами, вместо того, чтобы опираться на конкретные реализации. В данном примере, если в качестве типа переменной был бы использован интерфейс List, то смена реализации ArrayList на LinkedList решалась бы заменой всего одной строки не зависимо от масштабов проекта.