(по моему мнению), если кастинг не требуется, не делайте этого. Ваш код будет более читабельным.
В частности, синтаксис:
d.go(d);
более кратко и точно так же, как
d.go((Animal)d);
По сути, воспользуйтесь преимуществами расширения по причинам, которые я опишу ниже, в моей первой попытке ответить на ваш вопрос.
Ну, это зависит от того, что вы хотите, чтобы код выполнял.
Если вам нужна функция, которая может работать с любыми животными, собаками или иным образом, то вы должны взять в качестве входных данных животное.
Если вам нужна функция, которая требует чего-то, что есть только у собак, или которая имеет смысл только как операция, которая принимает собак в качестве входных данных, то вы должны принять в качестве входных данных собаку.
edit: возможно, более надуманный пример проиллюстрирует, почему это не вопрос с простым и универсальным ответом. В Java все объекты являются дочерними для Object, и поэтому любой метод может быть написан так, что он принимает параметр Object foo
.
Иногда это может быть полезно, но его варианты использования довольно ограничены, вы ограничены определенными методами в Object
.
Предположим, вместо этого вы знаете о Dog
, который также является Object
. Вместо того, чтобы передавать экземпляр Dog
как Object
, вы можете захотеть получить свойство определенное до Dog
. По сути, если вам нужно убедиться, что аргумент какой-либо функции соответствует какому-либо контракту, вы должны ограничить аргумент типами, которые соответствуют - немного по-другому: , если вам нужно знать, что это Dog, объявите его как Dog . * * 1033
Как правило, вы должны (на мой взгляд) выбирать «самый широкий» тип, который соответствует любому контракту, который вам нужно выполнить. Если вам нужно знать, что это животное, объявите его животным .