public class Foo : IFoo
...
В чем разница междуВ чем разница между IFoo Foo = новый Foo() и Foo Foo = новый Foo()
IFoo foo = new Foo();
и
Foo foo = new Foo();
public class Foo : IFoo
...
В чем разница междуВ чем разница между IFoo Foo = новый Foo() и Foo Foo = новый Foo()
IFoo foo = new Foo();
и
Foo foo = new Foo();
Разница только в объявленном типе переменной. Этот тип будет использоваться компилятором всякий раз, когда вы используете выражение foo
. Например, предположим, что класс Foo
содержит некоторый метод, который не является в IFoo
. С первым объявлением этот элемент не будет виден - вам нужно будет сделать foo
, чтобы набрать Foo
, чтобы позвонить ему. Во втором объявлении у вас будет прямой доступ к нему.
Обратное верно для членов IFoo
, которые реализованы с explicit interface implementation в Foo
. Это относительно редко, но это происходит.
С первым объявлением вы также можете переназначить переменную ссылкой на любой другой объект типа, реализующего IFoo
, например.
foo = new SomeOtherIFooImplementation();
тогда как второй декларации вы можете только присваивать значения, которые совместимы с Foo
- то есть экземпляры Foo
или производный класс. (В обоих случаях вы можете установить, что переменная должна быть нулевой, конечно.)
Часто полезно кодировать интерфейс, а не конкретную реализацию. Это означает, что компилятор не позволит вам использовать детали, специфичные для реализации, что, в свою очередь, означает, что в будущем может быть проще перейти на другую реализацию.
тип переменной также влияет на такие вещи, как разрешение перегрузки:
DoSomething(foo);
можно назвать различные методы в зависимости от того, объявляется foo
, как Foo
или IFoo
.
В принципе, переменная типа времени компиляции важна для всех видов - практически каждый раз, когда вы используете переменную, некоторый аспект значения этого кода будет зависеть от типа переменной.
Я хотел бы добавить, что любые члены IFoo, которые были явно реализованы в Foo, не отображаются во втором объявлении, но видны в первом. – Joren
@ Joren: Хороший звонок. Будет редактировать. –
Джон, у вас почти точный линейный рост вашей репутации, который увеличивается примерно на 15 700 каждый месяц. Учитывая часто задаваемые вопросы, вы можете получить максимум 200 реплеев в день, большинство из которых вы сможете получить в течение 30-дневного месяца - 6000 человек. Теперь, как ты ушел и получил в два раза больше? Ты показываешь нас здесь! –
Первый пример экземпляр некоторого объекта, реализующего IFoo. Второй пример - это экземпляр объекта Foo.
Если foo имеет тип IFoo, а Foo - реализованные методы или свойства, которые не определены в IFoo, вы не сможете получить к ним доступ, если только вы не нажмете foo на Foo.
Если foo имеет тип IFoo, вы можете создавать экземпляры других типов, которые также наследуются от IFoo и присваивать его foo. Это более абстрактно, поэтому вы не зависите конкретно от типа Foo.
Многие дубликаты вкл. http://stackoverflow.com/questions/1484445/why-are-variables-declared-with-their-interface-name-in-java –
также: http: // stackoverflow.com/questions/1595498/a-difference-in-style-idictionary-vs-dictionary –
В C# есть некоторые тонкости, которые не связаны с Java. Смотрите мой комментарий на ответ Джона. – Joren