Вы действительно спрашиваете: какой тип ссылки я должен использовать?
Как правило, вы хотите использовать как можно более общий тип ссылки, который все же дает вам доступ к нужному поведению.Это означает любой из интерфейсов или родительских классов вашего конкретного типа, а не сам конкретный тип.Конечно, не заходите слишком далеко - например, вы не хотите объявлять все как Object
!
Рассмотрите следующие варианты:
Set<String> values1 = new TreeSet<String>();
TreeSet<String> values2 = new TreeSet<String>();
SortedSet<String> values3 = new TreeSet<String>();
Все три действительны, но, как правило, первый вариант values1
лучше, потому что вы сможете получить доступ только к поведению интерфейса Set
, так что позже вы сможете легко заменить другую реализацию:
Set<String> values1 = new HashSet<String>();
Остерегайтесь использования второй опции values2
.Это позволяет вам использовать конкретное поведение реализации TreeSet
таким образом, что замена в другой реализации Set
становится более сложной.Это хорошо, если это ваша цель.Итак, в вашем примере используйте ссылку Car
или Bike
только тогда, когда вам нужен доступ к тому, чего нет в интерфейсе IVehicle
.Имейте в виду, что следующее не сработает:
TreeSet<String> values2 = new HashSet<String>(); // does not compile!
Тем не менее бывают случаи, когда вам нужен доступ к методам, которые не относятся к наиболее общему типу.Это проиллюстрировано в третьем варианте values3
- ссылка более конкретна, чем Set
, что позволяет вам полагаться на поведение SortedSet
позже.
TreeSet<String> values3 = new ConcurrentSkipListSet<String>();
Вопрос о ссылочных типахприменяется не только в тех случаях, когда объявляются переменные, но также и в методах, где необходимо указывать тип каждого параметра.К счастью, эмпирическое правило «используйте как общий тип ссылки, насколько это возможно» применимо и к параметрам метода.