Вы должны посмотреть на инверсию контроля:
В таком случае вы бы не написали так:
IInterface classRef = new ObjectWhatever();
Вы бы написали что-то вроде этого:
IInterface classRef = container.Resolve<IInterface>();
Это будет входить в основанную на правилах настройку container
объекта и создавать для вас реальный объект, который может быть ObjectWhh независимо. Важно то, что вы могли бы заменить это правило чем-то, что использовало бы совершенно другой тип объекта, и ваш код все еще работал бы.
Если мы оставим IoC вне таблицы, вы можете написать код, который знает, что он может общаться с объектом, который делает что-то конкретное , но не с тем, какой тип объекта или как он это делает.
Это пригодится при передаче параметров.
Что касается вашего вопроса в скобках «Кроме того, как вы могли бы написать метод, который принимает объект, который реализует интерфейс? Это возможно?», В C # вы просто использовали бы тип интерфейса для типа параметра, например так:
public void DoSomethingToAnObject(IInterface whatever) { ... }
Это включается прямо в «разговор с объектом, который делает что-то конкретное». Описанный выше метод знает, чего ожидать от объекта, что он реализует все в IInterface, но ему все равно, какой это тип объекта, только то, что он придерживается контракта, а именно интерфейс.
Например, вы, вероятно, знакомы с калькуляторами и, возможно, использовали в свое время немало, но в большинстве случаев они все разные. С другой стороны, вы знаете, как должен работать стандартный калькулятор, поэтому вы можете использовать их все, даже если вы не можете использовать специфические функции каждого калькулятора, которых нет ни у одного другого.
Это красота интерфейсов. Вы можете написать кусок кода, который знает, что ему будут переданы объекты, от которых он может ожидать определенного поведения. Не важно, что это за объект, только то, что он поддерживает необходимое поведение.
Позвольте мне привести вам конкретный пример.
У нас есть специальная система перевода для оконных форм. Эта система перебирает элементы управления в форме и переводит текст в каждом. Система знает, как обрабатывать базовые элементы управления, такие как свойство «тип элемента управления, который имеет текст», и аналогичные базовые элементы, но для чего-либо базового она не дотягивает.
Теперь, поскольку элементы управления наследуются от предопределенных классов, которые мы не можем контролировать, мы можем сделать одну из трех вещей:
- Создайте поддержку для нашей системы перевода, чтобы точно определить, с каким типом управления она работает, и перевести правильные биты (кошмар обслуживания)
- Встроить поддержку в базовые классы (невозможно, поскольку все элементы управления наследуются от разных предопределенных классов)
- Добавить поддержку интерфейса
Итак, мы сделали Nr. 3. Все наши элементы управления реализуют ILocalizable, который представляет собой интерфейс, который дает нам один метод, возможность переводить «себя» в контейнер текста / правил перевода. Таким образом, форме не нужно знать, какой тип элемента управления она нашла, только что она реализует определенный интерфейс и знает, что существует метод, который можно вызвать для локализации элемента управления.