Я использовал множество абстрактных классов как для полиморфизма, так и, очевидно, наследуя общую функцию в подклассах.Better Grasp on Interfaces
Я пытаюсь использовать интерфейсы больше. Да, это также используется для полиморфизма ... например, с использованием параметра IMyInterface в методе, который может принимать любой подкласс, который реализует IMyInterface.
Итак, теперь я не понимаю, почему мы должны или всегда должны определять наши переменные как IMyInterface, а не тип, который реализовал этот интерфейс.
Пример, посмотрите на эту статью:
http://weblogs.asp.net/sfeldman/archive/2008/02/14/understanding-ioc-container.aspx
Хорошо, в частности, это:
17: private static void AppCode()
18: {
19: ConsoleLogger logger = new ConsoleLogger();
20: Gadget gadget = new Gadget(logger);
21: gadget.TurnOn();
22: gadget.TurnOff();
23: }
24: }
25: }
AppCode method (lines 19-22) is what we are interested in. A few question can be raised at this point:
1. Why logger is of type ConsoleLogger and not ILogger? Isn't this wrong?
2. Why gadget is of type Gadget and not IGadget? Same smell?
3. What if we need to move logger implementer to a different layer than the ConsoleApp?
Вот что для меня, я не понимаю, почему это не проблема просто использовать конкретные методы Gadget и ConsoleLogger. Почему в этом верхнем слое все еще нужно быть var типа ILogger и IGadget? Я имею в виду, что на данный момент я не вижу необходимости в полиморфизме ... но я не вижу лодку, на мой взгляд, здесь, в моем учебном процессе.
Может кто-нибудь объяснить, почему каждый хочет создать параметры интерфейса в верхних слоях для переменные и присваивание этой переменной типу, который реализовал этот интерфейс? Почему не только Gadget и ConsoleLogger - это самый конкретный класс, который вы хотите использовать в первую очередь? Да Gadget и ConsoleLogger соответствуют контрактам ILogger и IGadget ... но Я должен упустить другую причину здесь. Основная причина.
Если у меня нет смысла, это потому, что я действительно не знаю, как описать свой вопрос, но я чувствую, что это довольно ясно. Зачем использовать интерфейсные переменные в случае как это?
Это похоже на то, что я видел там, когда вам нужно использовать конкретный тип, который реализовал интерфейс, который мне кажется, что вы всегда должны устанавливать его на переменную интерфейса, а не на переменный тип этого подкласса , Это правильно?
спасибо. Я не понимаю, что вы подразумеваете под «получить зависимости от классов, которые их используют» – PositiveGuy
(Предположим, вы хотели изменить ConsoleLogger на SyslogLogger или даже на CompositeLogger, который пишет в несколько хранилищ). Хорошо, поэтому вы говорите, что если я захочу перейти на другой журнал, то после того, как я уже выполнил регистрацию ILogger = new ConsoleLogger, я мог бы взять эту переменную регистратора и сделать logger = новый SyslogLogger, и теперь эта переменная указывает на новый тип регистратора через полиморфизм, поскольку SyslogLogger реализует ILogger? – PositiveGuy
@CoffeeAddict: добавлен ответ на 1-й комментарий – zerkms