Ключ к пониманию интерфейсов лежит в их сравнении с классами. Классы — это объекты, обладающие свойствами и методами, которые на эти свойства воздействуют. Хотя классы проявляют некоторые характеристики, связанные с поведением (методы), они представляют собой
предметы,
а не
действия,
присущие интерфейсам. Интерфейсы позволяют определять характеристики или возможности действий и применять их к классам независимо от иерархии последних. Допустим, у вас есть дистрибьюторское приложение, сущности которого можно упорядочить. Среди них могут быть классы
Customer, Supplier
и
Invoice.
Некоторые другие, скажем,
MaintenanceView
или
Document,
упорядочивать не надо. Как упорядочить только выбранные вами классы? Очевидный способ — создать базовый класс с именем типа
Serializable.
Но у этого подхода есть крупный минус. Одна ветвь наследования здесь не подходит, так как нам не требуется наследование всех особенностей поведения. С# не поддерживает множественное наследование, так что невозможно произвести данный класс от нескольких классов. А вот интерфейсы позволяют определять набор семантически связанных методов и свойств, способные реализовать избранные классы независимо от их иерархии.
Концептуально интерфейсы представляют собой связки между двумя в корне отличными частями кода. Иначе говоря, при наличии интерфейса и класса, определенного как реализующий данный интерфейс, клиентам класса дается гарантия, что у класса реализованы все методы, определенные в интерфейсе. Скоро вы это поймете на примерах.
Прочитав эту главу, вы поймете, почему интерфейсы являются такой важной частью С# в частности и программирования на основе компонентов вообще. Затем мы познакомимся с объявлением и реализацией интерфейсов в приложениях на С#. В завершение мы углубимся в специфику использования интерфейсов и преодоления врожденных проблем с множественным наследованием и конфликтами имен.