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