В чем же отличие формы от класса? В том, что создатели VB для удобства программистов снабдили формы механизмом визуализации. Это значит, что как в режиме проектирования, так и в режиме рабаты мы форму на экране видим. Специальные, скрытые от программиста методы рисуют и перерисовывают как форму, так и все ее элементы управления.
Класс же лишен механизма визуализации. Поэтому объекты, порожденные из него, невидимы. У них не может быть ни кнопок, ни меток, ни других элементов управления. Когда им надо сделать что-то "видимое", они "дергают за ниточки" форму и ее элементы управления, а также рисуют на их поверхности.
Правила обращения к переменным и процедурам.
Ниже под модулем понимается или форма, или класс, или стандартный модуль.
Просмотрите код процедуры Buttonl Click первой формы и коды процедур в остальных модулях и обратите внимание на то, как грамматически происходит обращение к переменным и процедурам. Вы увидите следующее:
Чтобы обратиться к переменной или процедуре, объявленным в стандартном модуле, достаточно написать имя переменной или процедуры без указания имени модуля.
Чтобы обратиться к переменной или процедуре, объявленным в классе, нужно перед их именем писать имя объекта этого класса с точкой.
Чтобы обратиться к переменной или процедуре, объявленным в форме, нужно перед их именем писать имя экземпляра класса этой формы с точкой.
Перед именем переменной или процедуры, объявленной в стандартном модуле, имя модуля писать не запрещено. Это бывает даже необходимо, когда в нескольких стандартных модулях объявлены переменные или процедуры с одинаковыми именами. Иначе их не различишь.
Все вышесказанное касается случая, когда нужно обратиться к переменной или процедуре, объявленным в чужом модуле. Когда же нужно обратиться к переменной или процедуре, объявленным в своем модуле, все просто: пишите имя переменной или процедуры и все. Иногда, правда, бывает удобно или даже необходимо указать имя хозяина или Me. Это не возбраняется (правда, в случае стандартного модуля слово Me писать нельзя).
Ниже для примера приведены разные способы обращения к собственной переменной, дающие один и тот же результат.
Вторая форма
Public F2 As String = "F2"
Public Sub Процедура_формы2()
Debug.WriteLine(F2)
Debug.WriteLine(Me.F2)
Debug.WriteLine(Форма2.F2)
End Sub
Второй модуль
Public М2 As String = "М2"
Public Sub Процедура_модуля2()
Debug.WriteLine(M2)
Debug.WriteLine(Module2.M2)
End Sub
Класс
Public C1 As String = "C1"
Public Sub Процедура_класса()
Debug. WriteLine(CI)
Debug.WriteLine(Me.CI)
Debug. WriteLine(Объект.C1)
End Sub
Из текста процедуры Buttonl Click становится также ясно, что с переменными и процедурами формы можно работать еще до того, как форма появилась на экране.
Создание нескольких объектов из одного класса
Создайте проект из формы, модуля и класса. На форму поместите кнопку. В окна кода введите такой текст:
Модуль
Module Modulel
Public Объект1 As New Класс
Public Объект2 As New Класс
End Module
Класс
Public Class Класс
Public С As Integer =10
Public Sub Процедура()
Объект1.С = 101
Объект2.С = 102
End Sub
End Class
Форма
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Buttonl .ClickDebug.WriteLine(Объект.C)
Debug.WriteLine (Объект2.С)
Объект1 .С = 1
Объект2.С = 2
Debug. WriteLine(Объектl.С)
Debug.WriteLine(Объект2.C)
Объект1.Процедура()
Debug. WriteLine(Объектl.С)
Debug.WriteLine(Обект2.C)
End Sub
Запустите проект, нажмите кнопку, проект напечатает следующее:
10; 10; 1; 2; 101; 102.
Мы видим, что модуль создает из класса Класс два объекта:Объект 1 и Объект2. При создании они абсолютно одинаковы и размещаются рядышком в оперативной памяти. Как выглядят они в оперативной памяти? Не нужно представлять себе, что каждый из них является копией программного текста из окна кода класса. Для нас важно знать, что в каждом объекте располагаются ячейки памяти под переменные, объявленные в классе. В нашем случае в каждом объекте располагается ячейка под переменную С.
В коде класса переменная С инициализируется значением 10, а это значит, что она станет такой в обоих объектах, что и подтверждают результаты выполнения первых двух строк процедуры Button1 Click.
После выполнения следующих двух строк процедуры объекты перестают быть близнецами. Теперь в ячейке С у первого объекта единица, а у второго - двойка, что и подтверждается печатью.
Объект может и сам изменять значения переменных, как в себе, так и в своем братце. Убедитесь в этом, просмотрев процедуру в классе.
Создание нескольких объектов-форм из одного класса формы
Создайте проект из двух форм и модуля. На форму 1 поместите кнопку, на форму 2 три кнопки.
В окна кода введите такой текст:
Модуль
Module Modulel
Public Форма1 As New Form2
Public Форма2 As New Form2
End Module
Форма 1 •
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Buttonl.Click
Форма1,Show()
Форма2.Show()
End Sub
Форма 2
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Buttonl.Click
Me.BackColor = Color.Blue
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.BackColor = Color.Red
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Форма.Text = "Форма”
Форма1.BackColor = Color.Black
Форма2.Техt = "Форма2"
Форма2.ВаскСо1ог = Color.White
End Sub
Запустите проект, нажмите кнопку формы 1, на экране появятся две совершенно одинаковые формы-близнеца. Даже заголовок у них одинаковый - Form2. При щелчках по первым двум кнопкам близнецов каждый близнец красит себя то в синий, то в красный цвет. Только себя, а не сестру. Потому что в коде написано Me. Таким образом, близнецы очень скоро перестают быть близнецами.
Третья кнопка показывает, что каждая из форм может изменять не только себя, но и сестру.
Все модули в одном
При создании классов и стандартных модулей при помощи меню: Project Add New Item для каждого стандартного модуля или класса автоматически создается свой файл и свое окно кода.
Но все стандартные модули и классы можно создавать в одном-единственном окне кода и в одном файле, причем даже в окне кода и файле формы.
Например, создайте проект и запишите в окне кода формы такой текст:
Public Class Forml
Inherits System.Windows.Forms.Form
Windows Form Designer generated code
'Сюда пишем код формы
End Class
Public Class Класс
'Сюда пишем код класса
End Class
Public Module Модуль
'Сюда пишем код модуля
End Module
Public Structure Структура
'Сюда пишем код структуры
End Structure
Вы видите в окне кода 4 равноправных модуля: два класса, один стандартный модуль и одну структуру. Как видите, VB не возражает. Отныне вы можете делать так всегда, а когда модули короткие, это даже удобно. Для этого подходит окно кода не только формы, но и класса и стандартного модуля. Причем ведут себя классы и стандартные модули совершенно так, как если бы были созданы в собственных файлах и имели собственное окно кода.
Области видимости
Когда проекты состоят из нескольких модулей, встает вопрос о видимости переменных, процедур и других элементов VB из других модулей. Чтобы элемент был виден из других модулей, достаточно объявить его не словом Dim, а словом Public..
В нижеприведенном примере приведены варианты объявлений переменных, констант, процедур и функций в типичном модуле.
Public Class Classl Dim С As Integer
Public A As Integer
Private В As Integer
Const M As Integer = 3
Public Const К As Integer = 1
Private Const L As Integer = 2
Private Sub Проц()
Dim C1 As Integer
End Sub
Sub Проц1()
Const L1 As Integer = 4
End Sub
Public Function Функц() As String
Static D As Integer
Return "Привет"
End Function
End Class
Мы различаем области видимости пяти уровней (в порядке увеличения охвата):
■ блок внутри процедуры или функции;
■ процедура или функция;
■ модуль;
■ проект;
■ неограниченная область (элемент виден из своего и из других проектов).
Последний случай актуален тогда, когда проект во время своей работы взаимодействует с другими проектами и должен видеть некоторые их элементы.
Рассмотрим области видимости начиная с самой узкой и кончая самой широкой.
Локальные переменные и константы.
Тем, в какой области будет виден тот или иной элемент, мы можем управлять при помощи так называемых модификаторов доступа. Модификаторов доступа всего 5: Public, Private, Protected, Friend, Protected Friend.
Внутри процедур и функций переменные могут быть объявлены только при помощи слов Dim и Static, а константы - только при помощи Const. Это блочная и локальная области видимости и локальные переменные и константы. Они видны только в той процедуре, функции или блоке, в которых объявлены.
Теперь поговорим об элементах, объявленных вне процедур и функций. Это и переменные, и константы, и процедуры, и функции, и модули. Они могут быть видны или только в том модуле, где они объявлены (независимо от того, насколько глубоко он угнездился внутри других модулей), или во всем проекте, или в неограниченной области в зависимости от того, при помощи каких слов это было сделано.
Область видимости - модуль.
Слова Dim или Private для переменной и слова Const или Private Const для константы делают их видимыми только в своем модуле. Их область видимости - весь этот модуль, включая все процедуры, функции и другие модули (если они есть) внутри модуля. Это модульные переменные и константы.
Обратите внимание, что здесь можно было бы обойтись и без модификатора Private. Но английский смысл слова Private ("частная собственность", "вход запрещен") лучше подходит к случаю, поэтому программисты в основном используют его.
Любой другой элемент (процедура, функция, модуль), чтобы быть видимым аналогичным образом только в своем модуле, объявляется модификатором Private.
Область видимости - проект, но не дальше. Если мы хотим, чтобы элемент VB был виден во всем проекте, но не дальше, мы объявляем его модификатором Friend. Часто программистам все равно - дальше или не дальше, и поэтому они употребляют вместо Friend более привычный модификатор Public, обеспечивающий неограниченную видимость.
Неограниченная область видимости.
Модификатор Public делает элемент неограниченно видимым. Часто такие элементы называют глобальными.
Видимость по умолчанию. Если вы совсем уберете модификатор доступа к классам, структурам и модулям:
Class Класс1
End Class
они по умолчанию будут иметь доступ Friend.
Если вы совсем уберете модификатор доступа к процедуре или функции они по умолчанию будут иметь доступ Public.
Имейте в виду, что элементу с неограниченной областью видимости не гарантирована эта неограниченная видимость, если он объявлен внутри элемента с ограниченной видимостью.
Область видимости - классы-наследники. Есть еще одна область видимости, которая не совпадает ни с одной из упомянутых и имеет отношение к наследованию классов. К ней относятся модификаторы Protected и Protected Friend.
Затенение
Переменные и другие программные элементы разных модулей или разных процедур вполне могут иметь одинаковые имена. Спрашивается, как VB определяет, какой из видимых одноименных элементов имеется в виду в каждом конкретном случае? Здесь вступает в действие эффект затенения: из нескольких одноименных элементов всегда имеется в виду более локальный, т. е. тот, чья зона видимости меньше. Это значит, что локальные элементы имеют предпочтение перед модульными, а те - перед глобальными. В этом есть глубокий смысл. Программист, объявляющий элемент в своей процедуре, может не заботиться о том, что где-то в модуле есть элементы с тем же именем. А программист, объявляющий элементы в своем модуле, может не заботиться о том, что элементы с тем же именем есть где-то в проекте.