Важную роль в системе ООП играют интерфейсы. Они определяют некоторый абстрактный функционал, не имеющий конкретной реализации, который уже реализуют
классы, наследующие эти интерфейсы. Определение интерфейса похоже на определения класса: интерфейс также может содержать свойства, методы и события.
Чтобы объявить интерфейс, надо использовать ключевое слово Interface (обратите внимание, что имена интерфейсов обычно начинаются с заглавной буквы
I). Итак, в прошлой главе мы создали небольшую систему из классов Person, Employee и Client, которые сейчас выглядят так:
Public MustInherit Class Person
Public Property FirstName() As String
Public Property LastName() As String
'Абстрактный метод
Public MustOverride Sub Display()
Public Sub New(fName As String, lName As String)
FirstName = fName
LastName = lName
End Sub
End Class
Public Class Employee
Inherits Person
Public Property Bank As String
Public Overrides Sub Display()
Console.WriteLine(FirstName & " " & LastName & " works in " & Bank)
End Sub
Public Sub New(fName As String, lName As String, _bank As String)
MyBase.New(fName, lName)
Bank = _bank
End Sub
End Class
Public Class Client
Inherits Person
Public Property Bank As String
Public Overrides Sub Display()
Console.WriteLine(FirstName & " " & LastName & " has an account in bank " & Bank)
End Sub
Public Sub New(fName As String, lName As String, _bank As String)
MyBase.New(fName, lName)
Bank = _bank
End Sub
End Class
Теперь добавим в наше приложение интерфейс IAccount, который будет содержать методы и свойства, которые понадобятся при работе с счетом клиента. Чтобы добавить интерфейс, в меню Project выберите пункт Add New Item... и в появившемся списке выберите пункт Code File. Назовите новый файл IAccount.vb. Будет создан пустой файл, и затем добавьте в него следующий код интерфейса:
Public Interface IAccount
'Текущая сумма на счете
ReadOnly Property CurentSum() As Integer
'Метод для добавления денег на счет
Sub Put(sum As Integer)
'Метод для снятия денег со счета
Sub Withdraw(sum As Integer)
'Процент начислений
ReadOnly Property Procentage() As Integer
End Interface
Обратите внимание, что методы и свойства не имеют реализации, в этом они сближаются с абстрактными методами абстрактных классов. Сущность нашего интерфейса
проста: он определяет два свойства для текущей суммы денег на счете и ставки процента по вкладам и два метода для добавления денег на счет и изъятия
денег. Теперь нам надо реализовать интерфейс в классе Client, так как клиент у нас обладает счетом. Чтобы реализовать интерфейс,
нам надо использовать ключевое слово Implements. Изменим класс Client следующим образом:
Public Class Client
Inherits Person
Implements IAccount
'Переменная для хранения суммы
Dim _sum As Integer
'Переменная для хранения процента
Dim _procentage As Integer
Public Property Bank As String
'Текущая сумма на счете
ReadOnly Property CurentSum() As Integer Implements IAccount.CurentSum
Get
Return _sum
End Get
End Property
'Метод для добавления денег на счет
Sub Put(sum As Integer) Implements IAccount.Put
_sum += sum
End Sub
'Метод для снятия денег со счета
Sub Withdraw(sum As Integer) Implements IAccount.Withdraw
If sum <= CurentSum Then
_sum -= sum
End If
End Sub
'Процент начислений
ReadOnly Property Procentage() As Integer Implements IAccount.Procentage
Get
Return _procentage
End Get
End Property
Public Overrides Sub Display()
Console.WriteLine(FirstName & " " & LastName & " has an account in bank " & Bank)
End Sub
Public Sub New(fName As String, lName As String, _bank As String, _sum As Integer)
MyBase.New(fName, lName)
Bank = _bank
Me._sum = _sum
End Sub
Обратите внимание, что класс, реализующий интерфейс, обязан реализовать все его свойства, методы и события. Интерфейсы, как и классы, могут наследоваться:
Public Interface IDepositAccount
Inherits IAccount
'Начисление процентов
Sub GetIncome()
End Interface
Зачем же нужны интерфейсы, если по сути они ничего не делают, только объявляют методы и свойства? Во-первых, интерфейсы позволяют реализовать концепцию множественного наследования. Если некоторый класс может иметь только один базовый класс, то при этом он может реализовать множество интерфейсов. Во-вторых, они более гибки по сравнению с классами, так как не содержат конкретной реализации.