Инструкция Implements
Задает интерфейс или класс, реализуемый в модуле класса, в котором он находится.
Синтаксис
Реализует [ Класс InterfaceName | ]
Обязательный элемент InterfaceName или Class — это имя интерфейса или класса в библиотеке типов, методы которой реализуются соответствующими методами в классе Visual Basic.
Замечания
Интерфейс — это коллекция прототипов, представляющих члены (методы и свойства), инкапсулируемые интерфейсом; то есть содержит только объявления для процедур-членов. Класс предоставляет реализацию всех методов и свойств одного или нескольких интерфейсов. Классами предоставляется код, используемый при вызове каждой функции контроллером класса. Все классы реализуют хотя бы один интерфейс, который считается интерфейсом по умолчанию для класса. В Visual Basic любой элемент, который не является явно элементом реализованного интерфейса, является неявно элементом интерфейса по умолчанию.
Когда класс Visual Basic реализует интерфейс, класс Visual Basic предоставляет собственные версии всех открытыхпроцедур , указанных в библиотеке типов интерфейса. Помимо предоставления сопоставления между прототипами интерфейса и пользовательскими процедурами оператор Implements заставляет класс принимать COM-вызовы QueryInterface для задаваемого идентификатора интерфейса.
Примечание.
В Visual Basic не реализуются производные классы и интерфейсы.
Когда реализуют интерфейс или класс, необходимо включить все задействованные процедуры Public. При отсутствии элемента в реализации интерфейса или класса возникает ошибка. Если не поместить код в одну из процедур в реализуемом классе, возникнет соответствующая ошибка (Const E_NOTIMPL = &H80004001), так что пользователь реализации поймет, что какой-то элемент не реализован.
Оператор Implements не может находиться в стандартном модуле.
Пример
В следующем примере показывается, как следует применять оператор Implements, чтобы сделать набор объявлений доступным нескольким классам. Предоставляя общий доступ к объявлениям через оператор Implements никакому классу не требуется делать отдельно какие-либо объявления. В примере также показано, как использование интерфейса позволяет абстрагироваться: переменную строгого типа можно объявить с помощью типа интерфейса. Затем ему можно назначить объекты разных типов классов, реализующие интерфейс.
Предположим, что существует две формы: SelectorForm и DataEntryForm. Форма выбора содержит две кнопки: Данные клиента и Данные поставщика. Чтобы ввести имя и адрес клиента или поставщика, пользователь нажимает кнопку клиента или кнопку поставщика в форме селектора, а затем вводит имя и адрес с помощью формы ввода данных. Форма ввода данных содержит два текстовых поля: Имя и Адрес.
Следующий код для объявлений интерфейса находится в классе с именем PersonalData:
Public Name As String
Public Address As String
Код, поддерживающий данные клиента, находится в модуле класса Customer. Обратите внимание, что интерфейс PersonalData реализуется с элементами, именуемыми с именем PersonalData_
интерфейса в качестве префикса.
Implements PersonalData
'For PersonalData implementation
Private m_name As String
Private m_address As String
'Customer specific
Public CustomerAgentId As Long
'PersonalData implementation
Private Property Let PersonalData_Name(ByVal RHS As String)
m_name = RHS
End Property
Private Property Get PersonalData_Name() As String
PersonalData_Name = m_name
End Property
Private Property Let PersonalData_Address(ByVal RHS As String)
m_address = RHS
End Property
Private Property Get PersonalData_Address() As String
PersonalData_Address = m_address
End Property
'nitialize members
Private Sub Class_Initialize()
m_name = "[customer name]"
m_address = "[customer address]"
CustomerAgentID = 0
End Sub
Код, поддерживающий данные поставщика, находится в модуле класса с именем Поставщик:
Implements PersonalData
'for PersonalData implementation
Private m_name As String
Private m_address As String
'Supplier specific
Public NumberOfProductLines As Long
'PersonalData implementation
Private Property Let PersonalData_Name(ByVal RHS As String)
m_name = RHS
End Property
Private Property Get PersonalData_Name() As String
PersonalData_Name = m_name
End Property
Private Property Let PersonalData_Address(ByVal RHS As String)
m_address = RHS
End Property
Private Property Get PersonalData_Address() As String
PersonalData_Address = m_address
End Property
'initialize members
Private Sub Class_Initialize()
m_name = "[supplier name]"
m_address = "[supplier address]"
NumberOfProductLines = 15
End Sub
Следующий код поддерживает форму Selector :
Private cust As New Customer
Private sup As New Supplier
Private Sub Customer_Click()
Dim frm As New DataEntryForm
Set frm.PD = cust
frm.Show 1
End Sub
Private Sub Supplier_Click()
Dim frm As New DataEntryForm
Set frm.PD = sup
frm.Show 1
End Sub
Следующий код поддерживает форму ввода данных :
Private m_pd As PersonalData
Private Sub SetTextFields()
With m_pd
Text1 = .Name
Text2 = .Address
End With
End Sub
Public Property Set PD(Data As PersonalData)
Set m_pd = Data
SetTextFields
End Property
Private Sub Text1_Change()
m_pd.Name = Text1.Text
End Sub
Private Sub Text2_Change()
m_pd.Address = Text2.Text
End Sub
Обратите внимание, что в форме ввода данных переменная m_pd объявляется с помощью интерфейса PersonalData, и ей могут быть назначены объекты класса Customer или Supplier , так как оба класса реализуют интерфейс PersonalData.
Также обратите внимание, что переменная m_pd может обращаться только к членам интерфейса PersonalData. Если ему назначен объект Customer , участник CustomerAgentId недоступен. Аналогичным образом, если ему назначен объект Поставщика , элемент NumberOfProductLines для поставщика недоступен. Назначение объекта переменным, объявленным с помощью различных интерфейсов, обеспечивает полиморфное поведение.
Также обратите внимание, что классы Customer и Supplier , как определено ранее, не предоставляют члены интерфейса PersonalData. Единственный способ получить доступ к членам PersonalData — назначить объект Customer или Supplier переменной, объявленной как PersonalData. Если требуется поведение, похожее на наследование, класс Customer или Supplier предоставляет элементы PersonalData, в класс необходимо добавить открытые члены. Их можно реализовать путем делегирования реализации интерфейса PersonalData.
Например, класс Customer можно расширить следующим образом:
'emulate PersonalData inheritance
Public Property Let Name(ByVal RHS As String)
PersonalData_Name = RHS
End Property
Public Property Get Name() As String
Name = PersonalData_Name
End Property
Public Property Let Address(ByVal RHS As String)
PersonalData_Address = RHS
End Property
Public Property Get Address() As String
Address = PersonalData_Address
End Property
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.