Преобразование типов

Последнее обновление: 30.10.2015

Ранее мы уже говорили о преобразовании простейших типов. Теперь затронем тему преобразования объектов различных классов. Итак, у нас есть следующая система классов:

'Классы
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
    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

End Class

'Интерфейсы
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

Public Interface IDepositAccount
    Inherits IAccount

    'Начисление процентов
    Sub GetIncome()

End Interface

В иерархии классов мы можем проследить следующую цепь наследования: Object (все классы неявно наследуются от типа Object) -> Person -> Employee|Client.

Из этой цепи видно, что объект класса Client одновременно является и представителем классов Person и Object. Поэтому мы можем создать объекты обоих классов следующим образом:

Dim emp As Object = New Employee("John", "Thompson", "City Bank")
Dim cl As Person = New Client("Tom", "Johnson", "City Bank", 100)

emp.Display()
cl.Display()

В данном случае работает неявное преобразование, так как наши переменные представляют классы Object и Person, поэтому допустимо неявное восходящее преобразование - преобразование к типам, которые находятся вверху иерархии классов:

Object
|
Person
|
Employee|Client

Таким образом, классы Employee и Client находятся в низу иерархии классов. Добавим еще класс Manager, который будет производным от Employee и поэтому будет находиться в самом низу иерархии классов.

Public Class Manager
    Inherits Employee
    
    Public Overrides Sub Display()
        Console.WriteLine(FirstName & " " & LastName & " is a manager of " & Bank)
    End Sub

    Public Sub New(fName As String, lName As String, _bank As String)
        MyBase.New(fName, lName, _bank)
    End Sub

End Class

Значит, мы можем написать следующее, так как объект класса Manager в то же время является и сотрудником банка:

Dim man As Employee = New Manager("John", "Thompson", "City Bank")
man.Display()

В то же время, если мы применим нисходящее преобразование, как в следующем коде, то мы получим ошибку:

Dim emp As Manager = New Employee("John", "Thompson", "City Bank")
emp.Display()

Здесь мы преобразуем объект Emloyee к типу Manager, однако если Manager является объектом типа Emloyee, то объект Emloyee не является объектом типа Manager. Есть несколько способов избежать ошибки при выполнении программы. Во-первых, можно использовать оператор TryCast - он пытается преобразовать выражение к определенному типу, при этом не выбрасывает исключение. В случае неудачного преобразования выражение будет содержать значение Nothing:

Dim emp As New Employee("John", "Thompson", "City Bank")
Dim man As Manager = TryCast(emp, Manager)
If man Is Nothing Then
    Console.WriteLine("Преобразование прошло неудачно")
Else
    man.Display()
End If

Второй способ заключается в отлавливании исключения InvalidCastException, которое возникнет в результате преобразования:

Try
    Dim emp As New Employee("John", "Thompson", "City Bank")
    Dim man As Manager = DirectCast(emp, Manager)
Catch ex As InvalidCastException
    Console.WriteLine("Преобразование прошло неудачно")
End Try

Третий способ заключается в проверке допустимости преобразования с помощью ключевого слова Is:

Dim emp As New Employee("John", "Thompson", "City Bank")
If TypeOf emp Is Manager Then
    Dim man As Manager = DirectCast(emp, Manager)
Else
    Console.WriteLine("Преобразование недопустимо")
End If

Выражение TypeOf emp Is Manager указывает, имеет ли переменная emp тип Manager. А поскольку такая проверка вернет False, то преобразование не сработает. Для явного преобразования типов используется оператор DirectCast, который пытается преобразовать переменную emp к типу Manager.

Все сказанное выше в отношении преобразования типов характерно и для интерфейсов. Поскольку класс Client реализует интерфейс IAccount, то переменная типа IAccount может хранить ссылку на объект типа Client:

Dim cl As IAccount = New Client("John", "Thompson", "City Bank", 200)
cl.Put(200)
Console.WriteLine("Остаток на счете : {0}", cl.CurentSum)
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850