Важную роль в системе ООП играют интерфейсы. Они определяют некоторый абстрактный функционал, не имеющий конкретной реализации, который уже реализуют
классы, наследующие эти интерфейсы. Определение интерфейса похоже на определения класса: интерфейс также может содержать свойства, методы и события.
Чтобы объявить интерфейс, надо использовать ключевое слово 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
Зачем же нужны интерфейсы, если по сути они ничего не делают, только объявляют методы и свойства? Во-первых, интерфейсы позволяют реализовать концепцию множественного наследования. Если некоторый класс может иметь только один базовый класс, то при этом он может реализовать множество интерфейсов. Во-вторых, они более гибки по сравнению с классами, так как не содержат конкретной реализации.