Механика реализации интерфейса. Нетривиальное применение интерфейсов.
Во многих компаниях, занимающихся программированием (хотя бы в Microsoft), существует должность ведущего программиста или ведущего специалиста по тестированию. Предположим, вы решили расширить систему учета кадров и включить в нее эти новые должности с особыми свойствами – скажем, наличием фонда материального поощрения для особо отличившихся подчиненных.
В описанной выше иерархии классов VB.NET определить новый класс "ведущий специалист" не удастся, поскольку классы Programmer и Tester уже являются производными от класса Employee, а множественное наследование в .NET не поддерживается. Перед нами идеальный пример ситуации, когда вам на помощь приходят интерфейсы.
Примечание
По общепринятым правилам имена интерфейсов в .NET начинаются с прописной бук-вы "I", поэтому в следующем примере интерфейс называется ILead.
Прежде всего интерфейс необходимо определить. В отличие от VB6, где интерфейс был обычным классом, в VB.NET появилось специальное ключевое слово Interface. Предположим, наши "ведущие" должны оценивать своих подчиненных и тратить средства из фонда материального поощрения. Определение интерфейса выглядит так:
Public Interface ILead Sub SpendMoraleFund(ByVal amount As Decimal) Function Rate(ByVal aPerson As Employee) As String Property MyTeam() As Empl oyee () Property MoraleFuod() As Decimal End Interface
Обратите внимание – в определении интерфейса отсутствуют модификаторы уровня доступа Publiс и Private. Разрешены только объявления Sub, Function и Property с ключевыми словами Overloads и Default. Как видите, определение интерфейса выглядит просто. Любой класс, реализующий интерфейс ILead, обязуется содержать:
- процедуру с параметром типа Decimal;
- функцию, которая получает объект Employee и возвращает строку;
- свойство, доступное для чтения и записи, возвращающее массив объектов Employee;
- свойство, доступное для чтения и записи, возвращающее значение типа Decimа1.
Как будет показано ниже, имена методов реализации несущественны – главное, чтобы методы имели заданную сигнатуру.
Чтобы реализовать интерфейс в классе, прежде всего убедитесь в том, что он сам или ссылка на него входит в проект. Далее за именем класса и командой Inherits в программу включается строка с ключевым словом Implements, за которым следует имя интерфейса. Пример:
Public Class LeadProgrammer Inherits Programmer Implements Head End Class
Имя Head подчеркивается синей волнистой чертой, свидетельствующей о возникшей проблеме. Тем самым компилятор настаивает на выполнении обязательств по реализации интерфейса хотя бы пустыми методами.
Как это сделать? В отличие от ранних версий VB, где члены классов, входящие в реализацию интерфейса, обозначались особой формой сигнатуры, в VB.NET используется более наглядный синтаксис. В следующем фрагменте соответствующая строка выделена жирным шрифтом.
Public Function Rate(ByVal aPerson As Employee) As String _ Implements ILead.Rate End Function
Конечно, имена членов интерфейса обычно совпадают с именами методов, их реализующих, но это не обязательно. Например, следующий фрагмент вполне допустим.
Public Property OurMoraleFund() As Decimal Implements Head.MoraleFund Get Return m_Moral e Fund End Get Set(ByVal Value As Decimal) m_MoraleFund =Value End Set End Property