Инструкция 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 и обратная связь.