ПОНЯТНО О Visual Basic NET (том 3)

       

Перегрузка


Перегрузка (Overloading) – ситуация, когда в коде класса присутствует несколько процедур с одинаковыми именами, делающих одно и то же дело, добивающихся одних и тех же результатов, и различающихся только параметрами.

Этот термин применим не только к процедурам, но и к функциям, и к свойствам, и к конструкторам.

С перегрузкой мы в этой книге встречались не раз. Перелистайте книжку назад и загляните в 6.2.8. Там вы увидите 4 варианта метода DrawLine класса Graphics. Все эти варианты различались количеством или типом параметров метода. Программист мог выбирать вариант по вкусу или по возможностям.

Придаем функциям параметры. Давайте применим перегрузку на нашем садовом участке. Но сначала, поскольку перегрузка имеет смысл только при наличии параметров, перепишем функции нашего класса, включив в них параметры:

Public Class Участок

    Public Владелец As String

    Public Высота_забора As Integer

    Public Shared Расход_краски_на_кв_м As Integer

    Public Function Периметр(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer

        Return 2 * (Длина + Ширина)

    End Function

    Public Function Площадь_забора(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer

        Return Периметр(Длина, Ширина) * Высота_забора



    End Function

    Public Function Расход_краски_на_забор(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer

        Return Расход_краски_на_кв_м * Площадь_забора(Длина, Ширина)

    End Function

End Class

Обратите внимание вот на что. Мы отказались от полей Длина и Ширина, так как  теперь объект получает их значения в виде параметров. Теперь извне мы должны обращаться к функциям с указанием параметров, например, так:

        Debug.WriteLine(Участок1.Расход_краски_на_забор(100, 50))

Это в чем-то удобно, в чем-то – нет. Неудобно, в частности, вот в чем. Если мы захотим включить параметры только в функцию периметра, оставив две другие функции без параметров, у нас ничего не получится. Ведь в тело функции Площадь_забора входит вызов функции Периметр с параметрами, а откуда взять их значения, если нет полей? Только из собственных параметров. По той же причине придется снабдить параметрами и функцию Расход_краски_на_забор.


Создаем перегрузку. Подготовку закончили. Теперь будем создавать перегрузку. Пусть некоторые пользователи не знают длину и ширину прямоугольного участка, зато они знают координаты его противоположных углов. Для удобства таких пользователей напишем второй вариант функции Периметр:

    Public Function Периметр  _

(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer

        Return    2 * (Math.Abs(X1 - X2) + Math.Abs(Y1 - Y2))

    End Function

Пояснения:  Math.Abs(X1 - X2) – не что иное, как длина участка, Math.Abs(Y1 - Y2) – высота.

Поместим эту функцию в код класса рядом с ее тезкой. У одной функции 2 параметра, у другой – 4. Когда вы будете обращаться к этой функции, VB по числу параметров догадается, к какой именно функции из двух вы обращаетесь.

Сказавший «А» должен сказать и «Б». Если вы хотите вычислять с этими 4 параметрами также и расход краски, вам придется сделать перегрузку и остальных двух процедур. Вот какой получится у вас код класса:

Public Class Участок

    Public Владелец As String

    Public Высота_забора As Integer

    Public Shared Расход_краски_на_кв_м As Integer

    Public Function Периметр(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer

        Return 2 * (Длина + Ширина)

    End Function

    Public Function Периметр  _

(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer

        Return 2 * (Math.Abs(X1 - X2) + Math.Abs(Y1 - Y2))

    End Function

    Public Function Площадь_забора(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer

        Return Периметр(Длина, Ширина) * Высота_забора

    End Function

    Public Function Площадь_забора  _

(ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer

        Return Периметр(X1, Y1, X2, Y2) * Высота_забора

    End Function

    Public Function Расход_краски_на_забор(ByVal Длина As Integer, ByVal Ширина As Integer) As Integer



        Return Расход_краски_на_кв_м * Площадь_забора(Длина, Ширина)

    End Function

    Public Function Расход_краски_на_забор  _

( ByVal X1 As Integer, ByVal Y1 As Integer, ByVal X2 As Integer, ByVal Y2 As Integer) As Integer

        Return Расход_краски_на_кв_м * Площадь_забора(X1, Y1, X2, Y2)

    End Function

End Class

А вот как можно проверить работу наших перегруженных функций, вычислив два раза расход краски на одном и том же участке (сначала участок задан длиной и шириной, а второй раз – координатами):

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim Участок1 As New Участок

        Участок1.Владелец = "Римский"

        Участок1.Высота_забора = 3

        Участок1.Расход_краски_на_кв_м = 2

        Debug.WriteLine(Участок1.Расход_краски_на_забор(100, 50))

        Debug.WriteLine(Участок1.Расход_краски_на_забор(1000, 2000, 1100, 2050))

End Sub

Перегруженные компоненты класса могут иметь и одинаковое число параметров. Тогда, чтобы VB их не перепутал, хотя бы у одного параметра должны быть разные типы.

Чтобы подчеркнуть, что компоненты перегруженные, вы можете писать в их заголовке слово Overloads.

Не путайте перегрузку с полиморфизмом. Перегрузка толкует о тезках в одном классе, полиморфизм – в разных; перегруженные функции получают один результат, полиморфные – разный.


Содержание раздела