Мне действительно пока не нравятся эти ответы.Они делают что-то простое, звучащее сложным.
Переменная - это просто держатель для ссылки.
Как видно из ваших примеров, тип переменной не обязательно должен соответствовать точномутип ссылки, которую он содержит.Переменная должна быть равной или более общей (или, если хотите, равной или менее конкретной ), чем ее ссылка.Car
является более общим, чем Ford
, так что присвоение в порядке.
Каждая ссылка может храниться в переменной Object
, поскольку это самый общий тип , который существуетв Java.
Object foo = new Car(1, 6);
Object bar = "hello world";
Теперь, проблема с этими переменными состоит в том, что мы можем вызывать методы только из класса Object
.Объявляя переменную как Object
, когда я пытаюсь получить доступ к содержимому, я могу использовать только методы из Object
независимо от того, что там действительно хранится.
В Object
есть несколько методов (например, toString
), так что это может быть хорошо, но в большинстве случаев присвоение Object
не очень полезно.
Итак,чем конкретнее мы обращаемся к нашим переменным, тем больше функциональности мы потенциально получаем к доступу.
Когда вы говорите
Car car = new Ford("ford", 6);
, могут существовать некоторые специфические для Ford функции, к которым мы не можем обратиться при обращениик нему из этой переменной.Мы всегда можем обойти это позже, приведя экземпляр, но вам следует избегать этого, если это абсолютно не необходимо.
Однако, чем более мы общие, тем более гибким становится наш код.Если метод принимает в качестве параметра только автомобили Ford, это довольно ограничительно.Если в качестве параметра можно использовать любой автомобиль, он более гибкий.
В общем, при выборе правильного типа для переменной вы можете мысленно начать с самого общего типа, который вы можете, и затем сохранитьсделав его более конкретным, пока он не будет соответствовать вашему варианту использования.
Например, если вы затем можете предпочесть Iterable
над Collection
, предпочитаете Collection
над List
и предпочитаете List
надArrayList
.