2009-11-01 4 views
1
public class Foo : IFoo 
... 

В чем разница междуВ чем разница между IFoo Foo = новый Foo() и Foo Foo = новый Foo()

IFoo foo = new Foo(); 

и

Foo foo = new Foo(); 
+0

Многие дубликаты вкл. http://stackoverflow.com/questions/1484445/why-are-variables-declared-with-their-interface-name-in-java –

+0

также: http: // stackoverflow.com/questions/1595498/a-difference-in-style-idictionary-vs-dictionary –

+1

В C# есть некоторые тонкости, которые не связаны с Java. Смотрите мой комментарий на ответ Джона. – Joren

ответ

10

Разница только в объявленном типе переменной. Этот тип будет использоваться компилятором всякий раз, когда вы используете выражение foo. Например, предположим, что класс Foo содержит некоторый метод, который не является в IFoo. С первым объявлением этот элемент не будет виден - вам нужно будет сделать foo, чтобы набрать Foo, чтобы позвонить ему. Во втором объявлении у вас будет прямой доступ к нему.

Обратное верно для членов IFoo, которые реализованы с explicit interface implementation в Foo. Это относительно редко, но это происходит.

С первым объявлением вы также можете переназначить переменную ссылкой на любой другой объект типа, реализующего IFoo, например.

foo = new SomeOtherIFooImplementation(); 

тогда как второй декларации вы можете только присваивать значения, которые совместимы с Foo - то есть экземпляры Foo или производный класс. (В обоих случаях вы можете установить, что переменная должна быть нулевой, конечно.)

Часто полезно кодировать интерфейс, а не конкретную реализацию. Это означает, что компилятор не позволит вам использовать детали, специфичные для реализации, что, в свою очередь, означает, что в будущем может быть проще перейти на другую реализацию.

тип переменной также влияет на такие вещи, как разрешение перегрузки:

DoSomething(foo); 

можно назвать различные методы в зависимости от того, объявляется foo, как Foo или IFoo.

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

+4

Я хотел бы добавить, что любые члены IFoo, которые были явно реализованы в Foo, не отображаются во втором объявлении, но видны в первом. – Joren

+0

@ Joren: Хороший звонок. Будет редактировать. –

+0

Джон, у вас почти точный линейный рост вашей репутации, который увеличивается примерно на 15 700 каждый месяц. Учитывая часто задаваемые вопросы, вы можете получить максимум 200 реплеев в день, большинство из которых вы сможете получить в течение 30-дневного месяца - 6000 человек. Теперь, как ты ушел и получил в два раза больше? Ты показываешь нас здесь! –

0

Первый пример экземпляр некоторого объекта, реализующего IFoo. Второй пример - это экземпляр объекта Foo.

1

Если foo имеет тип IFoo, а Foo - реализованные методы или свойства, которые не определены в IFoo, вы не сможете получить к ним доступ, если только вы не нажмете foo на Foo.

Если foo имеет тип IFoo, вы можете создавать экземпляры других типов, которые также наследуются от IFoo и присваивать его foo. Это более абстрактно, поэтому вы не зависите конкретно от типа Foo.

Смежные вопросы