Параметры объектного типа
В качестве параметров мы пока использовали переменные числовых и строкового типов. Параметр – это переменная. Переменная может иметь объектный тип. Значит и параметр может иметь объектный тип. Как это понимать и какая от этого польза? Рассмотрим два примера. Пример 1. Параметр типа Control. Для задания размеров элемента управления требуется два оператора – один для ширины, другой – для высоты. Предположим, вы хотите обойтись одним. Особого смысла в этом нет, но для иллюстрации подойдет. Создайте проект и поместите на форму метку и две кнопки. Введите такой код: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Настраиваем_размер(Button2, 80, 30) Настраиваем_размер(Label1, 100, 120) End Sub
Sub Настраиваем_размер(ByVal Элемент_упр As Control, ByVal Ширина As Integer, ByVal Высота As Integer) Элемент_упр.Width = Ширина Элемент_упр.Height = Высота End Sub Пояснения. Оператор Настраиваем_размер(Button2, 80, 30) делает ширину кнопки Button2 равной 80, а высоту – 30. А оператор Настраиваем_размер(Label1, 100, 100) делает ширину метки Label1 равной 100, а высоту – 120. Мы добились того, чего хотели. Как это у нас получилось? Оба приведенные оператора являются вызовами процедуры пользователя Настраиваем_размер. Посмотрите на ее заголовок. Первый параметр – Элемент_упр – имеет тип Control – объектный тип элементов управления. Это значит, что он может, например, принимать значение любого элемента управления на форме. Обязательно зайдите в пошаговый режим и обратите внимание, что переменная Элемент_упр, как и положено параметру, инициализируется, несмотря на то, что она не обычная, а объектная. Пока мы не зашли в процедуру Настраиваем_размер, она, естественно, не инициализирована и подсказка просто сообщает, что она объявлена, как мы и задали, типом System.Windows.Forms.Control. Здесь System.Windows.Forms – пространство имен, в которое входит класс Control. Но как только VB заходит в процедуру, переменная Элемент_упр становится объектом класса System.Windows.Forms.Button. При втором обращении – System.Windows.Forms.Label. Пример 2. Параметр типа Graphics. Вам уже предлагалось в Задание 78 написать процедуру пользователя для рисования крестика. У той процедуры были привычные нам параметры: координаты и размер крестика. Сейчас же нам интересен другой параметр. Мы хотим посредством него управлять тем, на поверхности какого элемента управления (или на форме) рисовать крестик. Создайте проект и поместите на форму метку и кнопку. Чтобы не отвлекаться, забудем о параметрах для координат и размера крестика. Введите такой код: Dim Графика_для_формы As Graphics Dim Графика_для_метки As Graphics
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Графика_для_формы = Me.CreateGraphics Графика_для_метки = Label1.CreateGraphics Рисуем_крестик(Графика_для_формы) Рисуем_крестик(Графика_для_метки) End Sub
Sub Рисуем_крестик(ByVal Гр As Graphics) Гр.DrawLine(Pens.Blue, 100, 110, 120, 110) Гр.DrawLine(Pens.Blue, 110, 100, 110, 120) End Sub Пояснения. Крестики рисуются на форме и на метке. Как видите, здесь параметром процедуры пользователя является объект класса Graphics. Без этого параметра мы не смогли бы пользоваться процедурой Рисуем_крестик для рисования крестика на разных элементах управления. Получилось бы только на одном. Пример 3. Функция объектного типа. Создайте проект с кнопкой, меткой и текстовым полем. Пусть нам наскучило обращаться к элементам управления, как положено, по именам, а «желаем» по номерам. Пронумеруем их в уме как-нибудь, например, кнопка – 1, метка – 2, текстовое поле – 3. Пусть возникла задача напечатать, на сколько кнопка превосходит по вертикальному размеру текстовое поле. В соответствии с нашим желанием нам не хочется писать так: Debug.WriteLine(Button1.Height - TextBox1.Height) а хочется писать что-нибудь вроде этого: Debug.WriteLine(Элемент(1).Height - Элемент(3).Height) Можем ли мы так сделать? Можем. Достаточно написать функцию: Function Элемент(ByVal Номер As Integer) As Control Select Case Номер Case 1 Return Button1 Case 2 Return Label1 Case 3 Return TextBox1 End Select End Function Пояснения. Функция может возвращать значение почти любого типа, а не только простого. В том числе и объект. Наша функция Элемент имеет объектный тип Control. Это значит, что в зависимости от значения своего параметра Номер она может принять значение не числа и не строки, к чему мы привыкли, а элемента управления: Button1 или Label1, или TextBox1. Вы можете в обращении мысленно заменить Элемент(1) на Button1, а Элемент(3) – на TextBox1, тогда вам будет легче привыкнуть к записи. Самое приятное, что когда мы в обращении ставим точку после Элемент(1), то всплывает список компонентов. Это происходит потому, что VB знает, что функция имеет тип Control. Функция Элемент дает нам замечательное преимущество работать с пронумерованными элементами управления в цикле. Например, вот как можно находить суммарную ширину элементов управления: For i = 1 To 3 s = s + Элемент(i).Width Next В заключение признаюсь, что создатели VB давно уже поняли прелесть нумерации элементов управления и воплотили ее стандартными средствами – при помощи так называемых коллекций (см. 16.2). Соответствие типов Мы с вами уже привыкли, что сочиняя программу, нужно немножко заботиться о соответствии типов. Соответствие типов должно выполняться не только для параметров методов, но и в операторе присваивания, где тип выражения справа от знака равенства должен соответствовать типу переменной слева от него. Поэтому, например, следующий фрагмент VB выполнит гладко и без малейших вопросов: Dim a As Integer Dim b As Integer = 99 a = b + 2 А вот при попытке выполнить следующий фрагмент Dim a As Integer Dim s As String = "Привет" a = s VB выдаст ошибку: Cast from string "Привет" to type 'Integer' is not valid. Переводится сообщение так: «Преобразование строки "Привет" в тип Integer незаконно». Действительно, в какое число можно превратить строчку текста? Нонсенс. А зачем VB вообще что-то преобразовывал? А затем, что есть такое правило выполнения оператора присваивания: Вычислив в операторе присваивания выражение справа от знака равенства, VB смотрит, совпадает ли его тип с типом переменной слева от него. Если совпадает – хорошо, а если не совпадает, то пытается преобразовать его тип к нужному (тому, что слева). Если удается – хорошо, а если из соображений правильности, точности, безопасности или из каких-то других своих соображений VB посчитает, что такое преобразование незаконно или ненужно, он выдает сообщение об ошибке. Рассмотрим фрагмент: Dim a As Integer Dim b As Double = 1 a = b + 0.48 Он будет выполнен гладко, несмотря на то, что справа – Double, а слева – Integer. VB не возражает в данном случае преобразовать дробное число в целое. Несмотря на колоссальную потерю в точности (1 вместо 1.48), никаких сообщений или предупреждений мы не увидим. Это программист сам виноват, что объявил переменную целым типом. Так же гладко выполнится и следующий фрагмент: Dim a As Integer = 99 Dim s As String s = a Здесь VB преобразует число 99 в строку “99”. Соответствие типов требуется и при вызове процедур и функций с параметрами. При обращении к процедуре VB смотрит, совпадает ли тип параметра в обращении к процедуре с типом соответствующего параметра в заголовке объявления процедуры. Если совпадает – хорошо, а если не совпадает, то пытается преобразовать его тип к нужному (тому, что в объявлении). Если удается – хорошо, а если нет, VB выдает сообщение об ошибке. В подтверждение этих слов достаточно вспомнить Методы, «придирчивые» к типу параметров (6.2.8). Чтобы не было проблем, старайтесь объявлять переменные и параметры, между которыми должно соблюдаться соответствие, одинаковыми типами.
Популярное: Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (478)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |