Обьекты в Visual Basic |
Хочу сразу предупредить - то что вы будете читать здесь - ни в коем случае не является академическим описанием объектно ориентированного программирования. Более того - это нельзя назвать даже нормальной учебной статьей. То о чем я буду писать вероятнее всего уже вам знакомо, или вы обо всем этом догадывались. В то же время так, не совсем традиционно изложенная информация может в какой-то мере прояснить вам картину видения обьектов, сквозь призму Visual Basic. Так что - Вперед! 29 октября 1998г. Как вы уже несомненно слышали, версии Бэйсика начиная от
пятой и выше поддержвают создание почти полноценных обьектов. Почему
почти? Потому что полноценнные обьекты должны иметь возможность наследоваться,
а также поддерживать инкапсуляцию и
полиморфизм.
Не поленились посмотреть что я там в словарике написал? Ну, ну. Запомните
это - это основа, которую все равно надо знать. Так вот, из трех указанных
в Бэйсике, реализовано только два последних. Как-же. как-же закричат
любители правды - мы можем сослаться внутри обьекта на методы и свойства
другого класса и в результате получить эти самые методы и свойства к
использованию, как унаследованные. Правильно, но вы не наследуете обьект -
вы наследуете его интерфейсы. И
сейчас, давайте лучше плюнем на это - что дано, тем и пользуемся.А начнем
мы с самых азов. Что такое класс и как написать свой собственнный первый
объект.
Класс (а в Бэйсике он реализуеся добавлением в проект class module) это просто шаблон. Некая коробка, на которой большими буквами написано - то что лежит внутри это не просто код, это ОБЪЕКТ! Испугались? Вот и Windows такой надписи пугается, да так сильно, что все, что вы обьявили с волшебным словом Public превращается в свойства или методы объекта. Итак, добавили в проект класс модуль, в свойствах этого класс модуля изменили имя с бестолкового Class1 на MyFirstClass, и смело пишем Возвращаемся в форму, и на Form_load создаем обьект типа MyFirstClass: dim obj as new MyFirstClass obj. И тут справа от точки выпадает список свойств и методов нашего новоявленного объекта. То, что обозначенно пиктограмкой летящего зеленого кирпича - это методы, а листик с перстом указующим - свойства. Запоминаем эти обозначения, с ними вы встретитесь еще не раз, и не только в этом месте. Итак, листик содержит А, АА, ААА Чем между собой отличаются 2 последних ? А ничем, точнее почти ничем - функция может вернуть значение прямо в своем имени, а процедура только в одном или нескольких аргументах. Снаружи они выглядят одинаково, только немного по разному вызываются. Как мы можем использовать класс? Очень просто. Выбирайте один из методов или свойств обьекта obj.aa При этом выполнится код, содержашийся в процедуре АА. Любой объект проходит один раз при рождении через процедуру class_initialaize а при смерти - class_terminate Когда же происходят рождение и смерть Инстанса класса? Рождение (и инициализация) класса происходит при первом вызове метода или свойства объекта. Смерть класса наступает при уничтожении переменной, являющейся референсом (ссылкой на данный обьект - В нашем случае эта переменная obj). Последнее верно до тех пор, пока референс только один Мы дошли до интересного момента - это переменные ссылки на обьект. Вы можете спросить что же в них интересного? А интересного в них - поведение. Вы наверное слышали в детстве от мамы, что присвоить рефреренс объекту просто, надо сказать Set референс_name = Class_Object_name Ключевое слово SET обязательно. Декларация референс_name как обьекта, тоже обязательна. При этом происходит присваивание ссылки объекту (но не создание обьекта). Ссылка на обьект является полноценным "хозяином" этого обьекта, его именем. Зная это имя вы можете манипулировать свойствами, методами, участвовать в эвентах. А что будет если присвоить одной ссылке другую? Set референс2_name = референс_name Вы получите Две одинаковые и равноправные ссылки на обьект - Если убить одну, с самим обьектом ничего не случится. Вот если прибить и вторую... Да, я так вольно толкую о времени жизни этих ссылок. Естественно время жизни переменной оределяется тем, где эта самая преременная обьявленна. Если на General формы - то и умрет вместе с формой, если в процедуре - то по окончанию процедуры. Естественно существует способ убивать обьектные переменные - Set референс_name = Nothing Если референс на обьект(единственный референс) будет перенаправлен на другой обьект - смерти первому обьекту не миновать. Поэкспериментируйте с эвентами Initialize & Terminate класса, поместив туда мессадж боксы. Теперь про волшебное слово NEW - оно меняет смысл указанных выше присвоений Set референс_name = New Class_Object_name При этом вы создаете не ссылку на существующий обьект , а ссылку на Новую Инстанс этого обьекта. Сам этот несуществующий обьект еще не родится, (родится он при первом же обращении к свойствам или методам) но ссылка уже будет подготовлена. Так же как и раньше вы можете иметь несколько ссылок на один обьект (родившийся или не родившийся), но использование слова NEW создаст вам еще одну копию (инстранс). Ну и напоследок - ссылка это все-таки не класс из которого рожден обьект, поэтому конструкция типа Set референс2_name = NEW референс_name - вызовет ошибку времени выполнения. 05 Ноября 1998г. Обещанное продолжение:Начну , пожалуй с того , что открою вам тайну. Даже две. Первая, наиболее страшная, это то, что обьекты внутри состоят из обычного кода, который вы лихо лепите тысячами строк. Т.е. не надо ожидать увидить внутри классов что-то, чего вы не видите в обычных формах . Кстати, как дополнение к этой страшной тайне - формы, такие привычные и любимые нами формы - это тоже инстансы классов. Предопределенные заранее, уложенные в коллекцию форм, но в то же время просто объекты. Думаю к последнему факту мы еще вернемся. Вторая тайна, неким неуловимым образом тоже связанная с первой, состоит в том, что изнутри класса - обьект (инстанс этого класса), как таковой - не виден. Его там (внутри класс модуля) не существует и существовать не может. Зато ооттуда вы легко можете получить доступ ко всем свойствам и методам, так как это, не более чем переменные, процедуры и функции. Из того, что не встречалось вам в обычном программировании можно отметить специальные процедуры - Property Let, Property Get, Property Set. Интуитивно ясно, для чего предназначенны эти процедуры. Let - установить значение свойства , Get - получить у обьекта установленное значение, Set - то же что и первое, только для свойства типа объект. Предвижу вопросы типа "А зачем это вообще нужно? Мы легко создаем свойства объявляя в классе Public переменные." Да. Вы действительно можете, и обязательно будете это делать - только такие свойства - статические. Максимум на что они годятся - это хранить значения. Чаще же изменение значения свойства влечет за собой какое либо действие. Давайте рассмотрим тривиальный пример - наша форма [ Еще помните про первую тайну :-) ? ] уже имеет свойство StartUpPosition, однако это такое "одноразовое" свойство. Создадим нашему обьекту-форме еще одно свойство - Center. Это простое свойство будет иметь всего 2 значения - Да и Нет (boolean). В случае установки этого свойства в True Форма должна изменить свое положение, и переместится в центр экрана. В случае установки этого свойства в False Форма должна "вспомнить" свое прошлое положение.Для приготовления этого блюда вам понадобится кастрюля, свежее мясо... Впрочем отвлекся я куда-то в сторону. Так вот нам понадобится вспомнить про вторую тайну. Т.е. форма изнутри - совсем не обьект, и для обращения с ней, как с обьектом вам нужна вторая форма, чтобы "смотреть" на первую "снаружи". А внутри формы нужно добавить две переменные для хранения координат формы (мы ведь собираемся из восстанавливать по False), и Property Let & Property Get Последние две проще всего добавить так - откройте окно кода, затем выберите в меню Tools Бэйсика "Add Procedure", надписать Center, пометить Property и Public. После Ok, вы увидите в коде две новые процедуры. Что такое vNewValue? Собственно, это переменная, которая будет принимать значение передаваемое в свойство. Эта переменная Должна быть того же типа что и сам аргумент принимаемый и возвращаемый свойством. Естественно и Property Get Center должно быть того же типа. Так что меняем оба Variant на Boolean Далее нам необходимы две Private переменные MyLeft и MyTop (long), и еще одна , чтобы помнить какое же значение этого свойства установлено сейчас - blnCenter (boolean) Последняя нужна так же для передачи этого значения между Let и Get. Вот что получится: Option ExplicitДобавьте вторую форму, на нее 2 кнопки, и код Option Explicit
28 Ноября
1998г Тайну эту я вам уже выболтал в прошлом выпуске. Там внутри просто код. Ну и соотвественно все , что мы можем делать в обычном коде - можем и там. Какие возможности открывает перед нами запихивание кода в класс? А разные! Вот например такая задачка. Всем хороши коллекции. Но нередко необходимо ограничить количество элементов. Можем мы это сделать в оригинальной коллекции? Нет, не можем. Мы не в состоянии влезть внутрь реализованных встроенных свойств и методов. Зато мы можем написать собственный класс. Вот и давайте быстренько это сделаем.
Создать методы Remove, ADD, Item, Count - первая как
процедура, последние 3 как функции. Начнем с простой - Count : Public Function Count() As
Long Аналогично создаются и остальные - просто повторяете матоды
коллекции, принимая их аргументы. Остановимся на ADD: Public Function Add(Item As Variant, Key As String) As
Boolean Итак, обратите внимание - функция возвращает True только
если добавить удалось. Если не удалось - ложь. Второе - первый аргумент
обьявлен как variant - очень удобно, можно передать и строку, и число, и
даже обьект. И это не всегда плюс - тут у вас в руках еще один механизм
ограничениий - измените тип переменной, и получите коллекцию кнопок или
строк, или... 28 декабря
1998г Мы говорили уже о разных способах создания обьектов. Вы уже обращали внимание на то, что в разных случаях (тип библлиотеки класса exe или dll, значение свойства public ) свойство Instansing имеет различные доступные значения. Это естественно, так как это свойство определяет какой конретно тип доступа к экземплярам класса будет назначен. Для VB6 это свойство будет иметь 6 разных значений: 1 - Private 2 - PublicNotCreatable. 3 - SingleUse. 4 -GlobalSingleUse. 5 - MultiUse. 6 - GlobalMultiUse. Далее мы поговорим о:
Заинтересовало ? Почитайте еще здесь и здесь Словарик терминов Наследование Инкапсуляция
Инкапсуляцию можно тремя словами описать так обьект это "вещь в себе". Т.е. информация об обьекте - его свойства и методы содержатся в описании этого обьекта. Если вернуться к нашему магнитофону - то в описание магнитофона входит , например "двухкассетная дека", с тюнером и приемником FM. Методами в данном случае будут: перемотать ленту, воспроизводить, записывать. Полиморфизм
Полиморфизмом называют способность многих обьектов использовать один и тот же метод. При этом производимые действия будут зависить от того, какого типа обьект их инициировал. С магнитофоном тут пример не пойдет :-) А вот из Бэйсика - пожалуйста. Почти все контролы в бэйсике имеют метод SetFocus , но передаваться он будет именно тому контролу, который его вызвал. И в случае с кнопкой - это вызовет появление рамки, а в случае с текстбоксом - перенос курсора. Методы
Методы это в принципе то, как ваш обьект реагирует на события.. Возвращаясь к уже надоевшему магнитофону - вы просто нажимете кнопку Play (это событие) далее магнитофон начинает прокручивать пленку, усиливать сигнал ... Вам уже не надо обьяснять ему что делать дальше. Интерфейс
Интерфейсом для обьекта можно назвать набор связанных свойств и методов Инстанс класса
Инстансом называется одна копия обьекта загруженная в память. Одновременно в памяти может существовать много инстансов одного обьекта. Коллекции
Коллекции - как ясно из названия, это набор элементов, собранный в кучу. Тип элементов не существенен. Доступ к элементам осуществляется по текстовому уникальному ключу. Этот ключ присваевается элементу при добавлении в коллекцию. Так же до любого элемента коллекции можно добраться последовательным перебором. |