51470

Средства объектно-ориентированного программирования в Visual Basic

Конспект

Информатика, кибернетика и программирование

С классами студенты сталкивались практически во всех предыдущих темах. Объектноориентированное программирование и проектирование построено на классах. Очень важно обратить внимание на то что у класса две различные роли: модуля и типа данных. Вторая роль класса не менее важна.

Русский

2014-02-11

187.42 KB

27 чел.

Тема 5.3. Средства объектно-ориентированного программирования в  Visual Basic

5.3.1.  Две роли классов в ООП и типы данных в  Visual Basic

5.3.1.  Средства создание собственных базовых классов в  Visual Basic

5.3.2.  Взаимодействие, взаимное различие и сходство форм, модулей и классов

5.3.3.   Объектное программирование

5.3.4.  Задачи для самостоятельного решения по теме  «Введение в объектно-

           ориентированное программирование»

5.3.5.  Тестовые задания по теме « Введение в объектно-ориентированное

           программирование»

5.3.1.  Две роли классов в ООП и типы данных в  
Visual Basic
 

Язык программирования  Visual Basic  является объектно-ориентированным языком. Это означает, что все функциональные части приложения рассматриваются как объекты, содержащие в себе некоторые свойства, способные выполнять определенные методы и генерировать события.

С классами студенты сталкивались практически во всех предыдущих темах. Это были классы, предоставленные пользователю VS  .Net в виде библиотек классов .Net Framework.

Например, класс математических функций – System.Math, класс – System.Array, System.IO, форма и элементы управления  System.Form и другие.

 

Объектно-ориентированное программирование и проектирование построено на классах. Любую программную систему, построенную в объектном стиле, можно рассматривать как совокупность классов, возможно объединенных в проекты, пространства имен, решения, как это делается при программировании в Visual Studio .Net.

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

Во-первых, класс – это модуль, архитектурная единица построения программной системы. Модульность построения – основное свойство программных систем. В ООП программная система, строящаяся по модульному принципу, состоит из классов, являющихся основным видом модуля. Модуль может не представлять собой содержательную единицу, его размер и содержание определяется архитектурными соображениями, а не семантическими. Ничто не мешает построить монолитную систему, состоящую из одного модуля, – она может решать ту же задачу, что и система, состоящая из многих модулей.

Вторая роль класса не менее важна. Класс – это тип данных, задающий реализацию некоторой абстракции данных, характерной для задачи, в интересах которой создается программная система. С этих позиций классы, это не просто кирпичики, из которых строится система. Каждый кирпичик теперь имеет важную содержательную начинку. Представьте себе современный дом, построенный из кирпичей, и дом будущего, где каждый кирпич выполняет определенную функцию, один следит за температурой, другой – за составом воздуха в доме. Объектно-ориентированная программная система напоминает дом будущего.

Состав класса, его размер определяется не архитектурными соображениями, а той абстракцией данных, которую должен реализовать класс. Если создается класс Account, реализующий такую абстракцию как банковский счет, то в этот класс нельзя добавить поля из класса Car, задающего автомобиль.

Объектно-ориентированная разработка программной системы основана на стиле, называемом проектированием от данных. Проектирование системы сводится к поиску подходящих для данной задачи абстракций данных. Каждая из них реализуется в виде класса, которые и становятся модулями – архитектурными единицами построения нашей системы. В основе класса лежит абстрактный тип данных.

В хорошо спроектированной объектно-ориентированной системе каждый класс играет обе роли, так что каждый модуль нашей системы имеет вполне определенную смысловую нагрузку. Типичная ошибка – рассматривать класс, только как архитектурную единицу, объединяя под обложкой класса разнородные поля и функции, после чего становится неясным, какой же тип данных задает этот класс.

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

К типам значения относятся:

  1.  все числовые типы данных;
  2.  Boolean, Char и Date;
  3.  все структуры, даже если их члены являются ссылочными типами;
  4.  перечисления, поскольку их базовый тип всегда является SByte, Short, Integer Long, Byte, UShort, UInteger или ULong.

К ссылочным типам относятся:

  1.  String;
  2.  все массивы, даже если их члены являются типами значений;
  3.  типы классов, например Form;
  4.  делегаты.

Следующие элементы программирования не квалифицируются как типы, так как нельзя указывать ни один из них в качестве типа данных для объявленного элемента:

  1.  пространства имен;
  2.  модули;
  3.  события;
  4.  свойства и процедуры;
  5.  переменные, константы и поля.

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

Переменная типа данных Object содержит 32-разрядные (4-байтные) адреса, которые ссылаются на объекты. Переменной типа Object можно назначить любой ссылочный тип (строка, массив, класс или интерфейс). Переменная типа Object может также ссылаться на данные любого типа значения (числовые, Boolean, Char, Date, структуры или перечисления).

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

Значением Object по умолчанию является Nothing (пустая ссылка).

Переменной Object можно назначить переменную, константу или выражение любого типа данных. Чтобы определить тип данных, на который в данных момент ссылается переменная Object, можно использовать метод GetTypeCode( ) класса System..::.Type, как показано в приведенном ниже примере:

Dim myObject As Object

Dim datTyp As Integer

datTyp = Type.GetTypeCode(myObject.GetType())

В данном примере тип данных Object является ссылочным типом. Однако VB обрабатывает переменную Object в качестве типа значения, если она ссылается на данные типа значения.

Все типы данных и все ссылочные типы расширяются до типа данных Object. Это означает, что можно преобразовать любой тип к типу Object без ошибки.

Преобразование переменной типа Object в другой тип данных с помощью ключевого слова преобразования, например функция CType.

В следующем примере преобразуется переменная anObject в Integer и String тип:

Public Sub objectConversion(ByVal anObject As Object)

   Dim anInteger As Integer

   Dim aString As String

   anInteger = CType(anObject, Integer)

   aString = CType(anObject, String)

End Sub

Если известно, что содержимое переменной типа Object имеет определенный тип данных, желательно преобразовать переменную в этот тип данных. Если продолжать использовать переменную Object, то это вызовет, либо упаковку и распаковку (для типа значения), либо позднюю привязку (для ссылочного типа). Эти операции требуют большего времени для выполнения и снижают производительность.

5.3.2.  Средства создания собственных базовых классов в  Visual Basic

Пришло время создавать и использовать свои собственные классы в составе проектов, при этом необходимо понимать четкое разделение понятий класс и объект.

Во-первых,  рассмотрим, из каких  элементов состоит  содержимое класса, т.е.  структуру класса.  

      Каждый класс содержит (в теле класса могут быть объявлены) набор констант, полей, свойств, методов, конструкторов, событий, делегатов и другие классы (структуры, интерфейсы, перечисления), которые  обобщенно называют членами класса:

  1.  поля –  переменные, принадлежащие классу или экземпляру класса  (принадлежность к классу или экземпляру класса характерна не только для полей, но и для методов, событий и свойств);
  2.  методы – процедуры класса;
  3.  свойства – синтаксическая надстройка,  позволяющая осуществлять в форме вызов функции,  аналогичной  чтению/записи  переменной (например, можно  объявить свойство Возраст, и при попытке записи в него отрицательного значения выдавать ошибку);
  4.  события – синтаксическая надстройка, поддерживаемая компилятором и средой  VB, которая позволяет вызывать методы других объектов, подписавшихся на данное событие (например, подписавшись на событие Нажатие объекта,  Кнопка, подписавшийся объект каждый раз при нажатии кнопки будет получать уведомление в виде вызова метода).

События и делегаты будут  рассмотрены в Теме 5.4.. Основу любого класса составляют его конструкторы, поля и методы.

Поля класса синтаксически являются обычными переменными (объектами) языка. Их описание удовлетворяет обычным правилам объявления переменных. Содержательно поля задают представление той самой абстракции данных, которую реализует класс. Поля характеризуют свойства объектов класса. Необходимо напомнить, что когда создается новый объект класса, то этот объект представляет собой набор полей класса. Два объекта одного класса имеют один и тот же набор полей, но разнятся значениями, хранимыми в этих полях. Например, все объекты класса Person могут иметь поле, характеризующее рост персоны, но один объект может быть высокого роста, другой – низкого, а третий – среднего роста.

Каждое поле имеет модификатор (атрибут) доступа, принимающий одно из четырех значений: Public, Private, Protected, Friend.  Атрибутом доступа по умолчанию является атрибут Рrivate. Независимо от значения атрибута доступа все поля доступны для всех методов данного класса. Они являются для методов класса глобальной информацией, с которой работают все методы, извлекая из полей нужные им данные и изменяя значения полей в ходе работы. Если поля доступны только для методов класса, то тогда они имеют атрибут доступа Private, который можно опускать. Такие поля считаются закрытыми.

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

Но часто желательно, чтобы некоторые поля были доступны в более широком контексте. Если некоторые поля класса A должны быть доступны для методов класса B, являющегося потомком класса A, то такие поля следует снабдить атрибутом Protected. Такие поля называются защищенными. Если некоторые поля должны быть доступны для методов классов B1, B2, и так далее, дружественных по отношению к классу A, то такие поля следует снабдить атрибутом Friend, а все дружественные классы B поместить в один проект (assembly). Такие поля называются дружественными. Наконец, если некоторые поля должны быть доступны для методов любого класса B, которому доступен сам класс A, то такие поля следует снабдить атрибутом Public. Такие поля называются общедоступными или открытыми.

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

Методы, называемые свойствами (Properties), представляют специальную синтаксическую конструкцию, предназначенную для обеспечения эффективной работы со свойствами. При работе со свойствами объекта (полями) часто нужно решить, какой модификатор доступа использовать, чтобы реализовать нужную стратегию доступа к полю класса. Перечислим пять наиболее употребительных стратегий:

  1.  чтение, запись (Read, Write);
  2.  чтение, запись при первом обращении (Read, Write-once);
  3.  только чтение (Read-only);
  4.  только запись (Write-only);
  5.  ни чтения, ни записи (Not Read, Not Write).

Открытость свойств (атрибут Public) позволяет реализовать только первую стратегию. В языке VB принято, как и в других объектных языках, свойства объявлять закрытыми, а нужную стратегию доступа организовать через методы. Для эффективности этого процесса и введены специальные методы-свойства.

Рассмотрим вначале пример, а потом уточним синтаксис этих методов. Рассмотрим класс Person, у которого пять полей: fam, status, salary, age, health, характеризующих фамилию, статус, зарплату, возраст и здоровье персоны. Для каждого из этих полей может быть разумной своя стратегия доступа. Возраст доступен для чтения и записи, фамилию можно задать только один раз, статус можно только читать, зарплата недоступна для чтения, а здоровье закрыто для доступа, только специальные методы класса могут сообщать некоторую информацию о здоровье персоны. Вот как на VB можно обеспечить эти стратегии доступа к закрытым полям класса:

'Класс, задающий общие свойства и поведение личности

Public Class Person

   Public Enum Status1

       ребенок

       школьник

       студент

       работник

       пенсионер

   End Enum

   'поля (все закрыты)

   Dim fam As String = ""

   Dim health As String = ""

   Dim age As Integer = 0

   Dim salary As Integer = 0

   Dim status As Status1 = Status1.работник

   'методы - свойства

   'стратегия: Read,Write-once Чтение,запись при первом обращении)

  Public Property Fam1() As String

       Set(ByVal value As String)

           If (fam = "") Then fam = value

       End Set

       Get

           Return fam

       End Get

   End Property

 

   'стратегия: Read-only(Только чтение)

   Public ReadOnly Property GetStatus() As Status1

       Get

           Return status

       End Get

   End Property

  'стратегия: Read,Write (Чтение, запись)

 

   Public Property Age1() As Integer

       Set(ByVal value As Integer)

           age = value

           If (age < 7) Then

               status = "ребенок"

           ElseIf (age < 17) Then

               status = "школьник"

           ElseIf (age < 22) Then

               status = "студент"

           Else

               status = "служащий"

           End If

       End Set

       Get

           Return age

       End Get

   End Property

   ‘стратегия: Write-only (Только запись)

   Public WriteOnly Property Salary1() As Integer

       Set(ByVal value As Integer)

           salary = value

       End Set

   End Property

End Class

Каждая из этих составляющих класса, а также сам класс могут иметь так называемые модификаторы доступа, которые указывают область ее видимости. Значения модификаторов могут быть следующими:

  1.  Public – открытый класс или член класса, доступ к которому разрешен из любого места программного кода;
  2.  Private – класс или член класса, доступный только из контекста, в котором он объявлен, и во всех вложенных контекстах; т.е. если, например, свойство объявлено с модификатором Private, то оно доступно только из того же самого класса и из вложенных в него классов;
  3.  Friend – класс или член класса, доступный только внутри той же сборки, в которой объявлен  (в VB  сборка обычно соответствует всей программе, поэтому данный модификатор можно воспринимать как указание видимости только в пределах программы);
  4.  Protected – член, доступный только из самого класса и из наследующих классов (данный модификатор применим только к членам классов);
  5.  Protected Friend – объединение областей видимости Protected и Friend.

Наряду с модификаторами доступа, регламентирующими видимость, члены класса могут содержать модификаторы, устанавливающие их принадлежность к классу или к экземпляру класса. Члены класса, принадлежащие всему классу, называют разделяемыми (Shared) или статическими членами. Разделяемыми (статическими) членами являются свойства, процедуры и поля, которые разделяются всеми объектами класса, то есть  являются общими для всех объектов класса. Члены, которые принадлежат конкретному экземпляру класса, а не всему классу, называются экземплярными (Instance). Чтобы понять разницу между этими видами методов и полей (и как следствие – свойств и событий), необходимо более подробно рассмотреть механизм вызова методов и обращений к полям.

Объявление класса фактически задает последовательность расположения полей в памяти и способы вызова методов класса. При создании экземпляра класса (конкретного объекта) происходит выделение памяти согласно структуре полей класса. При вызове экземплярного метода в качестве неявного параметра ему передается информация об экземпляре класса, для которого вызван этот метод (в VB  эта неявная  ссылка обозначается ключевым словом Me, а ссылка на класс обозначается словом MyClass). При вызове статического метода такой информации не передается, поэтому статическая функция может быть вызвана и при отсутствии какого-либо экземпляра класса. Отсюда сразу вытекает ограничение, накладываемое на статические методы. Статический метод не может обращаться к нестатическим методам и полям своего класса без указания конкретного экземпляра.

При обращении к полю экземпляра класса доступ производится по смещению                   относительно начала положения экземпляра класса в памяти. В отличие от экземплярного поля, статическое поле не требует конкретного объекта, поскольку оно создается и инициализируется всего один раз. Статические поля аналогичны глобальным переменным.

Напомним, что классы библиотеки  .Net Framework использовались двояко: без создания объектов и с созданием объекта. В первом  случае, чтобы воспользоваться возможностями класса, необходимо было написать имя класса, точку и имя необходимого свойства или метода этого класса. Так использовались математические функции класса System.Math.  Во втором случае,  чтобы воспользоваться возможностями класса, необходимо сначала создать объект – экземпляр класса, а уж затем писать имя объекта. Так использовались потоковый ввод/вывод и классы StringBuilder и Array.

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

В проекте  новый класс создается аналогично стандартному модулю. Т.е. чтобы создать в проекте  новый класс, необходимо  щелкнуть на кнопке        Добавление нового элемента  (Add  New  Item)  стандартной панели инструментов или на команде  Добавить новый элемент… (Add New Item…) элемента  главного меню Проект (Project). Также можно использовать команду  Добавить класс… (Add Class…) элемента главного меню Проект (Project).  В результате выполнения одной из этих команд откроется диалоговое окно  Добавление нового элемента … (Add New Item…) , в котором следует выбрать шаблон Class и указать имя класса.

После нажатия на кнопку Добавить (Add)  в окне Редактор кода (Code Editor) появится новый пустой класс:

Public Class1

End Class

Класс проекта, созданный первым,   по умолчанию имеет имя Class1.vb, но это имя можно изменить в окне  Добавление нового элемента … (Add New Item…)  или, сделав щелчок правой кнопкой мыши на модуле класса в окне  Обозреватель решений (Solution Explorer), введя новое имя  класса.

После создания класса и добавления в него членов класса необходимо создать объекты этого класса. Для их создания используется служебное слово New, которое может применяться с присваиванием начального значения (инициализацией) или без него.

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

Dim  ИмяПеременной   As  New   ИмяКласса

Во втором случае описание переменной не связано с созданием объекта и имеет вид:

Dim   ИмяПеременной   As  ИмяКласса,

Объект создается позже в процессе выполнения программы путем выполнения присваивания:

ИмяПеременной  =  New ИмяКласса

Рассмотрим пример описания классов.

Пример 5.3.1-1. Описать простой  базовый класс.

Простой базовый класс, приведенный на рис. 5.3.1-1.

Public Class SampleBase ‘Базовый класс

    'набор полей с различными модификаторами доступа

 Private   privateVar As Integer

 Public    publicVar  As Integer

 Friend    friendVar  As Integer

 Protected protVar    As Integer

     

    'Открытый экземплярный метод класса

 Public Sub SomeMethod( )   

 privateVar = 5     ' Внутри класса доступны все его поля 

 End Sub

 

     'Закрытый экземплярный метод класса

 Private Function SomeOtherMethod( ) As Integer

 Return publicVar   ' Открытые поля доступны всегда 

  End Function

      

     'Открытое экземплярное свойство

 Public Property SomeProperty() As Integer 

 Get

       Return privateVar

      End Get 

 Set(ByVal Value As Integer)

  privateVar = Value  

 End Set

 

     End Property

 'Открытый статический метод класса

 Public Shared Sub SharedMethod()   

     

 End Sub 

End Class

Public Class Form1

     . . .

     ‘Точка входа в программу

     Private Sub Button1_Click(   )

  Dim a As New SampleBase

  a.friendVar    = 5      ‘Допустимо: обращение из той же программы   a.publicVar    = 6      ‘Допустимо: поле открыто

  a.privateVar   = 6      ‘Ошибка: поле класса закрыто

  а.SomeProperty = 5

  SampleBase.SharedMethod()'обращение к статическому методу: вместо

     End Sub                    'имени объекта указывается имя класса                                           

End Class

Рис. 5.3.1-1

В данном примере создается класс SampleBase. В классе SampleBase объявлен набор полей, методов и одно свойство. При попытке откомпилировать этот код будут выдано сообщение:

'sampleVBProject.SampleBase.privateVar'is not accessible  in thiscontext because it is 'Private'.

 Это показывает, что закрытые  (Private) члены не доступны вне контекста класса.

Обратите     внимание     на     имя     переменной     в     сообщении     об     ошибке:

sampleVBProject.SampleBase.privateVar

 

Оно представляет собой полное имя члена класса, которое состоит из пространства имен (sampleVBProject), имени класса (SampleBase), имени члена (privateVar).

Рассмотрим что такое New. Это – конструктор, представляющий собой специальный метод класса, позволяющий создавать объекты класса. Конструктор -  неотъемлемый компонент класса. Нет классов без конструкторов. Одна из синтаксических особенностей этого метода в том, что его имя должно совпадать с именем класса. Если программист не определяет конструктор класса, то к классу автоматически добавляется конструктор по умолчанию – конструктор без аргументов. Заметьте, если программист сам создает один или несколько конструкторов, то автоматического добавления конструктора без аргументов не происходит.

Как и когда происходит создание объектов? Чаще всего, при объявлении сущности в момент ее инициализации. Обратимся, к примеру, который описывает класс Person,  и рассмотрим создание двух объектов класса Person:

Dim   pers1   As  New    Person() 

Dim   pers2   As  New  Person("Петрова")

Объекты pers1, pers2 класса Person объявляются с инициализацией, задаваемой унарной операцией new, которой в качестве аргумента передается конструктор класса Person. У класса может быть несколько конструкторов – это типичная практика, – отличающихся сигнатурой. В данном примере в первой строке вызывается конструктор без аргументов, во второй строке для сущности pers2 вызывается конструктор с одним аргументом типа String. Разберем в деталях процесс создания:

Первым делом для объектов pers1 и pers2 создаются ссылки, пока висячие со значением null.

  1.  Затем в динамической памяти создается объект – структура данных с полями, определяемыми классом Person. Поля объекта инициализируются значениями по умолчанию: ссылочные поля – значением null, арифметические – нулями, строковые – пустой строкой. Эту работу выполняет конструктор по умолчанию, который можно считать всегда вызывается в начале процесса создания. Если поля класса проинициализированы, как в нашем примере, то выполняется инициализация полей заданными значениями.
  2.  Если вызван конструктор с аргументами, то начинает выполняться тело этого конструктора. Как правило, при этом происходит инициализация отдельных полей класса значениями, переданными конструктору. Так поле fam объекта pers2 получает значение «Петрова».
  3.  На заключительном этапе ссылка связывается с созданным объектом.

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

Зачем классу нужно несколько конструкторов? Дело в том, что в зависимости от контекста и создаваемого объекта может требоваться различная инициализация его полей. Перегрузка конструкторов и обеспечивает решение этой задачи.

Некоторая экзотика, связанная с конструкторами. Конструктор может быть объявлен с атрибутом Private. Понятно, что в этом случае внешний пользователь не может воспользоваться им для создания объектов. Но это могут делать методы класса, создавая объекты для собственных нужд со специальной инициализацией.

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

Shared Sub Person()

 Console.WriteLine("Выполняется статический конструктор!");

End Sub

Подводя итоги, можно отметить, что объекты создаются динамически в процессе выполнения программы, для создания объекта всегда вызывается тот или иной конструктор класса.

Если задача создания объектов полностью возлагается на программиста, то задача удаления объектов, после того, как они стали ненужными, в Visual Studio .Net снята с программиста и возложена на соответствующий инструментарий – сборщик мусора. В классическом варианте языка C++ деструктор также необходим классу, как и конструктор. В языке VB y класса может быть деструктор, но он не занимается удалением объектов и не вызывается нормальным образом в ходе выполнения программы. Также, как и статический конструктор, деструктор класса, если он есть, вызывается автоматически в процессе сборки мусора. Его роль в освобождении ресурсов, например файлов, открытых объектом.

Имя деструктора строится из имени класса с предшествующим ему символом ~ (тильда). Как и у статического конструктора, у деструктора не указывается модификатор доступа.

Заметьте, правильный стиль требует, чтобы среди конструкторов класса всегда присутствовал конструктор по умолчанию - конструктор без аргументов. В нашем случае тело этого конструктора пусто, поскольку все поля объявлены с инициализацией и конструктору нет смысла изменять эти значения. Часто имена формальных аргументов конструктора совпадают с соответствующими именами полей класса. Поэтому при присваивании полю объекта значения аргумента необходимо уточнить имя поля именем объекта. В данном случае речь идет о текущем объекте, имя которого фиксировано - Me. Обратите внимание, кроме конструктора без аргументов и полного конструктора, заданы конструкторы для частных случаев, когда в момент создания объекта известны только фамилия или фамилия и возраст личности.

5.3.3. Взаимодействие, взаимное различие и сходство форм, модулей и классов

 

Рассмотрим сначала взаимодействие, взаимное различие и сходство форм, модулей и классов на примере.

Пример 5.3.3-1. Создать проект из двух форм, двух модулей и класса.

Рассмотрим программный код,  представленный на рис. 5.3.2-1, а также результат его работы на рис. 5.3.3-2.

Module Module1

   Public Форма2 As New Form2

   Public Объект As New Класс

End Module

Module Module2

   Public M2 As String = "M2"

   Public Sub Процедура_модуля2()

       Форма2.F2 = "Модуль 2 изменил переменную F2 из формы 2"

   End Sub

End Module

Public Class Класс

   Public C1 As String = "C1"

   Public Sub Процедура_класса( )

       M2 = "Объект изменил переменную M2 из модуля M2" 

   End Sub

End Class

Public Class Form2

   Public F2 As String = "F2"

   Public Sub Процедура_формы2()

       Объект.C1 = _

           "Форма2 изменила переменную С1 из Объекта" & vbNewLine

       TextBox1.Text = Объект.C1

   End Sub

End Class

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, _

               ByVal e As System.EventArgs) _

               Handles Button1.Click

       Dim SS As String = ""

       SS = SS & M2 & vbNewLine

       SS = SS & Объект.C1 & vbNewLine

       SS = SS & Форма2.F2 & vbNewLine

       Процедура_модуля2( )

       SS = SS & Форма2.F2 & vbNewLine

       Объект.Процедура_класса()

       SS = SS & M2 & vbNewLine

       TextBox1.Text = SS

       Форма2.Процедура_формы2()

       Форма2.Show()

   End Sub

End Class

Рис. 5.3.3-1

Рис. 5.3.3-2

Рассмотрим сходство и различия трех модулей, а именно стандартного  Module2, модуля формы Form2 и модуля класса  Класс. Очевидно, что их код почти одинаков. Код всех этих трех модулей содержит объявление переменной и объявление процедуры. И переменная, и процедура объявлены как Public, чтобы и той, и другой можно было пользоваться из любого модуля проекта.

Когда форма, модуль и класс могут начать работу?

 

Если форма - стартовый объект, VB сам, без всякого вмешательства загружает ее и отображает на экране.

 Стандартные модули тоже безо всяких забот программиста готовы к работе и использованию сразу после запуска проекта.

Это значит, что форма Form1 и оба модуля готовы к работе и использованию сразу после запуска проекта.

Что же касается класса и не стартовой формы, здесь дело другое. В нашем проекте забота о том, чтобы они пришли в рабочее состояние, лежит на первом стандартном модуле.  Если необходимо использовать класс как объект, то, чтобы класс заработал, нам нужно из него создать объект. Что и делает оператор

Public Объект  As  New  Класс

   Форма тоже класс. А раз так, то, чтобы она заработала в проекте, из нее тоже должен быть создан объект и показан на экране.

Если форма - стартовый  объект, эти заботы берет на себя  VB.

 Если форма - не стартовый объект, программист должен сам создать ее как объект из ее класса, а затем показать на экране. Это можно реализовать с помощью двух операторов.

Оператора, который создает форму, как объект класса Form2:

Public  Форма2  As   New Form2

 

и  оператора, показывающего форму   Форма2.Show().

 

Строки стандартного модуля, объявляющие переменные, выполняются автоматически.

Поэтому объекты Объект и Форма2, объявленные в модуле Module1, будут созданы сразу же в начале работы проекта, так как стандартный модуль, в отличие от класса и формы (если она не стартовая, конечно) готов к работе сразу после запуска проекта.

 Когда программист в режиме проектирования работает над формой Form2, добавляет в нее элементы управления, пишет код, он создает и видит  перед собой класс (не объект) Form2. Когда же запускается проект и выполняется оператор   Public Форма2 As New Form2,  то порождается из этого класса объект Форма2, как экземпляр класса Form2. Форма (объект, а не класс) порождена, и можно пользоваться ее переменными и процедурами. Но на экране она не видна. Чтобы ее увидеть и пользоваться ее элементами управления, необходимо выполнить оператор Формa2.Show().  Аналогично, когда в режиме проектирования пишется код модуля класса, то создается класс, а когда запускается проект и выполняется оператор  Public  Объект As New Класс, то  порождается из этого класса объект Объект как экземпляр класса Класс.

В чем же отличие формы от класса? В том, что создатели VB для удобства                    разработчиков снабдили формы механизмом визуализации. Это значит, что как в режиме проектирования, так и в режиме работы форма на экране видима. Специальные, скрытые от программиста методы рисуют и перерисовывают как форму, так и все ее элементы управления.

Класс же лишен механизма визуализации. Поэтому объекты, порожденные из него, невидимы. У них не может быть ни кнопок, ни меток, ни других элементов управления.

 Еще раз рассмотрим правила обращения к переменным и процедурам. Ниже под модулем будем понимать или форму, или класс, или стандартный модуль.

Если переменная или процедура объявлены с помощью слова Public, то они видны и доступны не только из своего модуля, но и из других модулей проекта.

Грамматически обращение к переменным и процедурам разных модулей происходит следующим образом:

  1.  для обращения к переменной или процедуре, объявленным в стандартном модуле,          достаточно написать имя переменной или процедуры без указания имени модуля;
  2.  для обращения к переменной или процедуре, объявленным в классе, нужно перед их именем  написать имя объекта этого класса с точкой;
  3.  для обращения  к переменной или процедуре, объявленным в форме, нужно перед их именем писать имя экземпляра класса этой формы с точкой.

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

Все вышесказанное касается случая, когда необходимо обратиться к переменной или                процедуре, объявленным в чужом модуле. Когда же нужно обратиться к переменной или процедуре, объявленным в своем модуле, все просто: пишется имя переменной или процедуры.  Иногда, правда, бывает удобно или даже необходимо указать имя хозяина или Me. Это не возбраняется (правда, в случае стандартного модуля слово Me писать нельзя).

Пример 5.3.3-2. Способы обращения к собственной переменной.

Рассмотрим  разные способы обращения к собственной переменной, дающие один и тот же результат (рис. 5.3.3-3).

‘Вторая форма

Public F2 As String = "F2"

Public Sub Процедура_формы2()

 TextBox1.Text = F2 : TextBox1.Text = Me.F2 : TextBox1.Text = Форма2.F2

End Sub

‘Второй модуль

Dim SM1, SM2 As String

Public M2 As String = "M2" 

Public Sub Процедура_модуля2()

 SM1 = M2 : SM2 = Module2.M2

End Sub

'Класс

Dim SC1, SC2, SC3 As String

Public C1 As String = "C1" 

Public Sub Процедура_класса()

 SC1 = C1 : SC2 = Me.C1 : SC3 = Oбъект.C1

End Sub

Рис. 5.3.2-3

 Из текста процедуры Button1_Click( ) примера (рис. 5.3.3-1) становится также ясно, что с переменными и процедурами формы можно работать еще до того, как форма появилась на экране.

Пример 5.3.3-3.  Создать несколько объектов из одного класса.

Для создания нескольких объектов из одного класса необходимо создать проект из формы, модуля и класса. На форму поместить кнопку, текстовое поле и ввести  программный код, приведенный на рис. 5.3.3-4. Результат представлен на рис. 5.3.3-5.

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, _

           ByVal e As System.EventArgs) Handles Button1.Click

       Dim SS As String = ""

       SS = SS & CStr(Объект1.С) & vbNewLine

       SS = SS & CStr(Объект2.С) & vbNewLine

       Объект1.С = 1 : Объект2.С = 2

       SS = SS & CStr(Объект1.С) & vbNewLine

       SS = SS & CStr(Объект2.С) & vbNewLine

       Объект1.Процедура()

       SS = SS & CStr(Объект1.С) & vbNewLine

       SS = SS & CStr(Объект2.С) & vbNewLine

       TextBox1.Text = SS

   End Sub

End Class

Module Module1

   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

 Рис. 5.3.3-4

 

Рис. 5.3.3-5

Видно, что модуль создает из класса Класс два объекта: Объект1 и Объект2. При создании они абсолютно одинаковы и размещаются рядышком в оперативной памяти. В каждом объекте располагается ячейка под переменную С.

В программном коде класса переменная С инициализируется значением 10, а это значит, что она станет такой в обоих объектах, что и подтверждают результаты выполнения первых двух строк процедуры Button1_Click( ).

После выполнения следующих двух строк процедуры объекты перестают быть близнецами. Теперь в ячейке С  у первого объекта единица, а у второго – двойка.

Объект может и сам изменять значения переменных, как в себе, так и в своем «братце».  Это видно из кода процедуры в классе. Таким образом, родившись одинаковыми,  близнецы в процессе жизни могут изменяться.

 Пример 5.3.2-4.  Создать  несколько объектов-форм из одного класса формы.  Создадим проект из двух форм и модуля. На форму 1 поместите кнопку, на форму 2-3 кнопки. Покажем, что из одного класса формы можно порождать несколько объектов-форм, причем эти объекты ведут себя так же, как и объекты, порождаемые из модуля класса в предыдущем примере. Поскольку работа объектов-форм с переменными и процедурами неотличима от таковой работы прочих объектов, то ее рассматривать не будем, а займемся более наглядной работой с цветом фона.

Введем программный код, приведенный на рис. 5.3.2-6.

'Модуль

Module Module1

 Public Форма1 As New Form2

 Public Форма2 As New Form2

End Module

код Form1

Public Class Form1

 Private Sub Button1_Click(ByVal sender As System.Object, _

                           ByVal e As System.EventArgs) _

                           Handles Button1.Click

    Форма1.Show()

    Фopмa2.Show()

 End Sub

End Class

Форма 2

Public Class Form2

 Private Sub Button1_Click(ByVal sender As System.Object, _

                           ByVal e As System.EventArgs) _

                           Handles Button1.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

   Фopмa1.Text = "Форма1" 

   Форма1.BackColor = Color.Black

   Форма2.Техt = "Форма2" 

   Форма2.ВасkСоlоr = Color.White

 End Sub

End Class

Рис. 5.3.3-6

 

Запустить проект и  нажать кнопку формы 1, на экране будут отображены две совершенно одинаковые формы-близнеца с тремя кнопками каждая. Даже заголовок у них одинаковый - Form2. При щелчках по первым двум кнопкам близнецов каждый близнец красит себя,  то в синий, то в красный цвет. Только себя. Потому что в коде используется Me. Таким образом, близнецы очень скоро перестают быть похожими. Третья кнопка показывает, что каждая из форм может изменять не только себя, но и сестру.

 Ранее уже были рассмотрены  проблемы видимости, когда переменные, объявленные внутри процедуры, являлись локальными в процедуре, т. е. невидимыми снаружи процедуры. Поэтому их нельзя было использовать в других процедурах модуля.

Когда проект состоит из единственного модуля формы, рассмотренных ранее областей видимости было достаточно. Теперь, когда наши проекты состоят из нескольких модулей, встает вопрос о видимости переменных, процедур и других элементов VB из других модулей. Также уже известно, что для того, чтобы элемент был  виден из других модулей, достаточно объявить его не словом Dim, а словом Public.

 Обычно различают области видимости пяти уровней (в порядке увеличения охвата):

  1.  блок внутри процедуры или функции;
  2.  процедура или функция;
  3.  модуль;
  4.  проект;
  5.  неограниченная область.

 Для систематизации  знаний об областях видимости переменных,  констант и  процедур  рассмотрим пример.

Пример 5.3.3-5. Анализ области видимости.

Введем следующий программный код, приведенный на рис. 5.3.3-7.

Public Class Class1

  

  Dim C 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

    Dim D As Integer

    Return "Привет" 

 End Function

End Class

Рис. 5.3.3-7.

Проанализируем  работу примера и рассмотрим его области видимости, начиная с самой узкой и кончая самой широкой,  с учетом того, что областью видимости можно управлять при помощи модификаторов доступа (Public, Private, Protected, Friend, Protected Friend):

  1.  Локальные переменные и константы.

Внутри процедур и функций переменные могут быть объявлены только при  помощи  слова Dim, а константы - только при помощи Const.  Это знакомые блочная и локальная области видимости и знакомые локальные переменные и  константы. Они видны только в той процедуре, функции или блоке, в которых объявлены.

Теперь поговорим об элементах, объявленных вне процедур и функций. Это                       переменные, константы, процедуры и модули. Их пространство - три нижние области видимости. Они могут быть видны или только в том модуле, где они объявлены, или во всем проекте, или в неограниченной области в зависимости от того, при помощи каких слов объявление было сделано.

  1.  Область видимости - модуль.

Слова Dim или Private для переменной и слова Const или Private Const для константы делают их видимыми только в своем модуле. Их область видимости - весь этот модуль, включая все процедуры, функции. Это модульные переменные и константы.

Таким образом, для объявления модульных переменных и констант можно  обойтись и без модификатора Private (достаточно оператора Dim). Любой другой элемент (процедура, модуль), чтобы быть видимым аналогичным образом только в своем модуле, объявляется модификатором Private.

  1.  Область видимости - проект.

Если необходимо, чтобы элемент VB был виден во всем проекте, но не дальше, объявляем его модификатором Friend.  Часто программисты употребляют вместо Friend более привычный модификатор Public, обеспечивающий неограниченную видимость.

  1.  Неограниченная область видимости.

Модификатор Public делает элемент неограниченно видимым. Такие элементы называют глобальными для всего решения.

  1.  Видимость по умолчанию.

Если совсем убрать модификатор доступа к классам и модулям:

Class Класс1 

               ‘по умолчанию будут иметь доступ Friend

End Class                         

 

      Если совсем убрать модификатор доступа к процедуре:

Sub  Pr() 

               ‘по умолчанию будут иметь доступ Public.

End Sub

 Переменные и другие программные элементы разных модулей или разных процедур могут иметь одинаковые имена. Как в этом случае VB определяет, какой из видимых одноименных элементов имеется в виду в каждом конкретном случае? Здесь вступает в действие эффект затенения: из нескольких одноименных элементов всегда имеется в виду более локальный, т. е. тот, чья зона видимости меньше. Это значит, что локальные элементы имеют предпочтение перед модульными элементами,  а модульные  элементы – перед глобальными.

Подведем итог и сформулируем два правила:

  1.  Чем локальнее, тем лучше. 

Встает вопрос: какую область видимости необходимо  выбирать для каждой конкретной переменной?  Объявлять ли ее глобальной, модульной или локальной? Здесь совет один - любую переменную объявляйте как можно более локальной, пусть ее область видимости будет как можно меньше. Если ее значение нужно только в одной процедуре и больше нигде, делайте ее локальной. Если ее значение нужно в нескольких процедурах одного модуля, а в других модулях нет, то делайте ее модульной. И только если значение переменной нужно в нескольких модулях, делайте ее глобальной. Такой подход обеспечит вашему проекту максимальную надежность и удобство в отладке.

  1.  Используйте процедуры с параметрами.

Второе  правило: вместо процедур без параметров используйте процедуры с параметрами.

  1.  В общем, совет такой: с глобальными и модульными переменными работайте по возможности через параметры.

5.3.4. Объектное программирование

 Итак,  напомним, что такое объект.

 Объект - это синтез данных (в частности, переменных и констант) и действий (процедур), которые эти данные обрабатывают.

Объекты в программировании напоминают объекты реального мира, которые в некотором смысле представляют синтез данных и действий.

Почти все приложения Windows и сама операционная система Windows создана на основе объектного подхода. Типичные примеры объектов в Windows это окна, кнопки и пр. Все они характеризуются, с одной стороны, данными (размер,  цвет и пр.), а с другой стороны, действиями, которые определяют их поведение.

 Пример 5.3.4-1. Определение объектной модели игрушечного радиоуправляемого автомобиля.

Определим, где у игрушечного радиоуправляемого автомобиля данные и где действия.

 Данных у игрушечного автомобиля множество. Например, следующие:

  1.  цвет кузова;
  2.  номер автомобиля;
  3.  скорость движения в данный момент;
  4.  громкость звукового сигнала;
  5.  высота кресел;
  6.  величина электрического тока в двигателе в данный момент;
  7.  толщина гайки в таком-то месте внутри корпуса и т. д.

 Действий тоже достаточно. Например:

  1.  поворот по команде с пульта управления;
  2.  торможение по команде с пульта управления;
  3.  подпрыгивание автомобиля на маленьком камушке;
  4.  изменение скорости вращения электродвигателя при изменении в нем тока;
  5.  возникновение жужжания двигателя при трении шестеренок друг о друга и т. д.

 Определим "внешние" и "внутренние" данные и действия. Они бывают крупные и мелкие, важные и менее важные. Нас будут интересовать:

  1.  данные и действия, что видны или доступны для запуска автомобиля со
    стороны внешних объектов, например мальчика, держащего в руках
    пульт управления (такие данные и действия близки к понятию
    глобальных переменных и методов).
  2.  данные и действия, что не видны или недоступны (т.е. близки к понятию модульных).

Проведем дальнейшую детализацию и определим, какие данные являются свойствами. Таким образом, данные будем делить на те, что видны снаружи (это первые 5 свойств из списка), и те, что не видны (последние два). Данные, видимые снаружи, назовем свойствами объекта

Итак, свойства - это данные, видимые снаружи. Теперь будем подразделять свойства по доступности к изменению. Мы их разделим на две категории:

  1.  те, что можно произвольно менять снаружи (назовем их свойствами для чтения-
    записи);
  2.  те, что снаружи менять нельзя - последние 4 данных из списка (назовем их свойствами только для чтения).

Очевидно, что данные, которые не видны снаружи, и менять снаружи тоже нельзя. В программировании это локальные переменные или модульные переменные, объявленные модификаторами Dim или Private.

Действия разделим на те, которые можно вызывать снаружи (первые два действия из списка), и на те, что вызываются внутренним строением автомобиля (остальные). Действия, вызываемые снаружи, назовем методами объекта. В программировании это процедуры, объявленные, например, словом Public. Если процедуры  объявлены словом Private, то снаружи они не видны и методами не являются.

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

  1.  количество методов должно быть минимально необходимым (например, разгон, торможение, поворот налево и направо и  этого достаточно);
  2.  количество свойств для чтения-записи должно быть минимальным (если все данные сделать свойствами, да еще и для чтения-записи, тогда любой, кому не лень, сможет в любой момент менять все свойства).

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

Данные и действия объекта представляют собой единое целое, образующее всю механику объекта, и хранятся они в одной "упаковке". Упаковкой этой является класс. Они должны быть как можно меньше видимы снаружи. Хорошо инкапсулированный объект представляет собой некий "черный ящик". Вся работа идет внутри. Внутренние данные меняются при помощи внутренних действий. Никто снаружи не может вмешаться в эту внутреннюю работу. Наружу показывается лишь тот минимум, который необходим для связи с окружающим миром.

Влиять снаружи на работу объекта можно только тремя способами:

  1.  методами;
  2.  изменяя значения свойств  для чтения-записи;
  3.  изменяя свойства окружающей среды.

Таким образом, инкапсуляция - то, что объединяет объекты в программировании с объектами реального мира.

Теперь можно уточнить  терминологию.

 Данные, видимые снаружи,  делятся на свойства и на поля.

 Полем (Field) класса будем называть переменную, объявленную в этом классе при помощи Public или Friend:

Public С As Integer = 10

 Свойства (Properties) определяются при помощи  ключевого слова Property и описаны в примере 5.3.4-4. Пока же будем иметь дело только с полями.

Снаружи класса поля и свойства неотличимы, обращение к ним одинаково. Это позволило в начале данной темы неформально называть и то и другое свойствами.

 

Пример 5.3.4-2. Создание и использование двух объектов одного класса.

Пусть вы директор только что родившегося садового товарищества, в нем всего два участка. Однако вы уже решили использовать компьютер для решения повседневных задач.

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

 Полный программный код приведен на рис. 5.3.3-1.

Предполагается, что на форме имеется 6 текстовых полей (TextBox) и 3 кнопки (Button), а  проект должен действовать следующим образом.

 

В  5 текстовых полей вводится следующая информация, касающаяся первого участка:

TextBox1        Владелец участка;

TextBox2      Длина участка;

TextBox3        Ширина участка;

TextBox4        Высота забора на участке;

TextBox5       Расход краски на 1 кв. м забора.

После этого пользователь нажатием на кнопку Button1 создает из класса Участок объект Участок1, который принимает в себя все данные из текстовых полей в качестве своих полей.

Затем пользователь вводит в текстовые поля информацию, касающуюся второго участка и нажатием на кнопку Button2 создает из класса Участок объект Участок2, который также принимает в себя все данные из текстовых полей в качестве своих полей.

С этого момента в памяти находятся два объекта-экземпляра класса Участок. Программист теперь   как угодно может использовать их в своих целях. В качестве примера такого использования он может нажать на кнопку Button3 для решения следующей задачи: "Правда ли, что на покраску забора первого участка уйдет больше краски, чем для второго?"

Public Class Участок 

 Public  Владелец As String 

 Public  Длина, Ширина, Высота_забора As Integer 

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

 Private Периметр As Integer

 Private Sub Вычисляем_периметр(  )

    Периметр = 2 * (Длина + Ширина)

 End Sub

 Private Function Площадь_забора( ) As Integer

    Вычисляем_периметр( )

    Return Периметр * Высота_забора

 End Function

 Public Function Расход_краски_на_забор( ) As Integer

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

 End Function 

End Class

Public Class Form1

 Dim Участок1, Участок2 As Участок

 Private Sub Button1_Click(ByVal sender As System.Object, _

                         ByVal e As System.EventArgs)_

                         Handles Button1.Click

   Участок1 = New Участок 'Из класса рождается объект. 

   Участок1.Владелец              = TextBox1.Text
   Участок1.Длина                 =
CInt(TextBox2.Text)

   Участок1.Ширина                = CInt(TextBox3.Text)

   Участок1.Высота_забора         = CInt(TextBox4.Text)

   Участок1.Расход_краски_на_кв_м = CInt(TextBox5.Text)

 End Sub

 Private Sub Button2_Click(ByVal sender As System.Object, _

                         ByVal e As System.EventArgs)_

                         Handles Button2.Click

   Участок2 = New Участок 'Из класса рождается объект

   Участок2.Владелец              = TextBox1 Text

   Участок2.Длина                 = TextBox2.Text

   Участок2.Ширина                = TextBox3.Text

   Участок2.Высота_забора         = TextBox4.Text

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

 End Sub

Private Sub Button3_Click(ByVal sender As System.Object, _

                         ByVal e As System.EventArgs)_

                         Handles Button3.Click 

 If Участок1.Расход_краски_на_забор > Участок2.Расход_краски_на_забор Then

      TextBox6.Text="Пepвомy участку нужно больше краски, чем второму" 

 End If

End Sub

End Class

      Рис. 5.3.4-1

 В классе объявлено 5 переменных с ключевым  словом Public. Следовательно, они видны снаружи объекта. Значит, это поля объекта. К тому же Public без употребления других запретительных слов допускает свободное изменение значений поля снаружи объекта. Следовательно, это поля для чтения-записи.

Внутренняя механика объекта определяется его процедурами и функциями.

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

Процедура Вычисляем_периметр( ) вычисляет периметр. Сделали ее Private, так как пока никому снаружи она не нужна, всех интересует только расход краски. Если в будущем кому-то захочется вычислять периметр участка, поменяем Private на Public. По той же причине объявлена Private и переменная Периметр, которая ввиду этого полем не является и снаружи не видна. Класс Участок использует ее только как промежуточный результат вычислений.

Функция Площадь_забора( ) возвращает площадь забора. Мы сделали ее Private из аналогичных соображений.

Функция Расход_краски__на_забор( ) возвращает результат, который нужен снаружи (в нашем конкретном случае - процедуре Button3_Click( ), принадлежащей форме),  поэтому сделали ее Public. Следовательно, эта функция является методом.

Итак, был создан  класс с пятью полями и одним методом. Кроме этого, в нем есть переменная, процедура и функция,  каждая из которых невидима снаружи.

 Пример 5.3.4-3. Создание и использование массива объектов одного класса.

 Предположим, что садовое товарищество растет, и в нем уже несколько десятков участков. Надо менять проект. Теперь у нас на форме будет только две кнопки. Рождение каждого нового объекта будет происходить при нажатии одной и той же Button1. Когда все объекты будут рождены, их можно  как угодно использовать в своих целях. В качестве примера конкретной реализации, рассмотрим  ситуацию, когда от нажатия на Button2 распечатываются имена владельцев тех участков, на заборы которых ушло больше 200 кг краски (рис. 5.3.4-2).

Public Class Участок 

  Public Номер_участка As Integer 

  Public Владелец As String 

  Public Длина, Ширина As Integer 

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

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

  Private Периметр As Integer

  Private Sub Вычисляем_периметр()

    Периметр = 2 * (Длина + Ширина)

  End Sub

  Private Function Площадь_забора() As Integer

    Вычисляем_периметр()

    Return Периметр * Высота_забора

  End Function

  Public Function Расход_краски() As Integer

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

  End Function

End Class

Public Class Form1

Dim Участки(100) As Участок 

Dim k As Integer = 1

Private Sub Button1_Click(ByVal sender As System.Object, _

                           ByVal e As System.EventArgs)_

                           Handles Button1.Click

   Участки(k) = New Участок

   Участки(k).Номер_участка = k

   Участки(k). Владелец = TextBox1.Text

   Участки(k).Длина = CInt(TextBox2.Text)

   Участки(k).Ширина = CInt(TextBox3.Text)

   Участки(k).Высота_забора = CInt(TextBox4.Text)

   Участки(k).Расход_краски_на_кв_м = CInt(TextBox5.Text)

   k = k + 1

 End Sub

 Private Sub Button2_Click(ByVal sender As System.Object, _

                           ByVal e As System.EventArgs)_

                           Handles Button2.Click

  Dim i As Integer

  For i = 1 To k -1      'Всего участков k-1 

      If Участки(i).Расход_краски > 200 Then  

         TextBox6.Text = Учacтки(i).Владелец

      End If

  Next

End Sub

End Class

Рис. 5.3.4-2

Здесь вместо двух участков (Участок1 и Участок2) был объявлен массив из 101 участка.

От нажатия к нажатию Button1 значение переменной к увеличивается на единицу оператором   k = k + 1.

Поэтому оператор

Участки(k) = New Участок

рождает новый объект - экземпляр класса Участок - и заодно присваивает его очередному элементу массива Участки( ).

В классе Участок прибавилось новое поле - Номер_участка. В принципе снаружи оно никому не нужно, так как если мы обращаемся, скажем, к элементу массива                   Участки(8), то тем самым мы уже знаем, что это участок № 8.

 Пример 5.3.4-4. Использование функции вместо поля.

Вернемся к предыдущему примеру и предположим, что  кому-то снаружи класса понадобился периметр участка, а он его не видит, так как он объявлен Private. 

Сделаем его полем:  Public Периметр  As  Integer. Теперь он виден всем. И это хорошо. Плохо то, что теперь все смогут менять наш  периметр, например, оператором                 Участки(k).Периметр = 25.  Тогда вернем,  все как было: Private Периметр As Integer.

Но теперь недоволен заказчик: ему нужно знать периметр. Что же делать? Нужно устроить так, чтобы периметр был все-таки виден и в то же время защищен от посягательств. Читать - читайте, а менять извне его значение нельзя!

Для этого создадим функцию Периметр_участка( ): 

Public Function Периметр_участка( ) As Integer

  Return Периметр

End Function

 

Теперь любой желающий извне может узнать значение периметра.

Поскольку такие обращения к переменной и функции без параметров синтаксически неотличимы, то снаружи могут сколько угодно думать, что обращаются к переменной Периметр_участка, когда на самом деле это функция. Цель достигнута, так как присваивать значение функции мы можем только в ее теле, а уж никак не из других модулей.

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

Public Function Периметр_участка() As Integer 

  If Периметр > 10000 Then

    MsgBox("Периметр участка засекречен")

    Return 0

  Else

    Return Периметр + 1

  End If

End Function

Идея «функция вместо поля» в VB оформлена синтаксически в виде следующей заготовки:

Public Property Периметр_участка( ) As Integer 

  Get

  End Get

  Set(ByVal Value As Integer)

 End Set

End Property

Слово Property означает свойство. Периметр участка перестал быть просто переменной, перестал быть полем, перестал быть функцией, он стал свойством.

Слово Get означает «Получи значение свойства», а слово Set означает «Установи значение свойству».

Эта конструкция состоит из двух частей. Внутри части Get - End Get пишется код, показывающий значение свойства наблюдателю извне. Внутри части Set - End Set пишется код, позволяющий наблюдателю извне менять значение свойства. Об этой части поговорим чуть позже, а поскольку никто не собирается давать возможность изменения значений свойства извне, просто пока сотрем эту часть, а добавим в объявление свойства слово ReadOnly  (только для чтения):

Public ReadOnly Property Периметр_участка( ) As Integer 

 Get

   Return Периметр

 End Get

End Property

 Поставленная  задача решена.

 

Теперь займемся полями нашего класса, например, полем Длина. Хорошо бы при присвоении этому полю значения из текстового поля осуществлялся некоторый контроль значений. Например, мы хотим запретить участки длиннее 500 м. Однако поле Длина имеет тип Integer и поэтому допускает очень большие числа. Можно написать ограничение в коде формы, но это будет нарушением принципа инкапсуляции. Общепринятое средство - создать свойство.

Превратим переменную Длина из поля в модульную (локальную) переменную, защитив ее тем самым  от воздействия  извне:

Private Длина As Integer

а затем создадим свойство Длина_участка:

Public Property Длина_участка() As Integer

 Set (ByVal Value As Integer) 

      If Value < 500 Then

         Длина = Value  

      Else

         MsgBox("Cлишком длинный участок") 

       Длина = 0

    End If

 End Set

 Get

     Return Длина 

 End Get

End Property

Таким образом,  предоставлена возможность каждому извне узнавать без ограничений значение свойства, поэтому часть Get - End Get заполняется стандартно.

Поговорим о части Set - End Set. Внутренним хранителем значения длины в нашем классе является модульная переменная Длина. Свойство Длина_участка придумано только для того, чтобы показывать вовне значение этой переменной и по возможности безопасным и контролируемым образом разрешать извне это значение менять. Часть Set - End Set поэтому имеет своей конечной целью присвоение переменной Длина нужного значения.

Если часть Get - End Get - это функция, то часть Set - End Set - это процедура с параметром Value. Каждый раз, когда кто-то пытается извне присвоить свойству Длина_участка какое-нибудь значение, это значение приходит в объект-участок в качестве значения параметра Value свойства Длина_участка. Остается только написать в части
Set - End Set единственный оператор Длина = Value.

И если бы он остался единственным, то в этом случае мы получили бы свойство для чтения-записи безо всяких ограничений. Но ведь поле Длина обеспечивало, то же самое. Однако мы помнили о нашем запрете на длинные участки и поэтому часть Set - End Set сделали длиннее. Теперь каждый желающий из текстового поля задать длину участка, равную 500 и выше, столкнется с сообщением «Слишком длинный участок» и вынужден будет вводить данные вновь.

Обратите внимание, что классу совершенно все равно, что физически является передатчиком значения извне внутрь свойства. Это может быть текстовое поле, как в нашем случае, или InputBox( ), или файл. В любом случае значение приходит в объект в качестве значения параметра Value и анализируется согласно коду, написанному в теле свойства программистом.

Итак,  обычная последовательность создания свойств:

  1.  организуется модульная переменная Private –  хранительница значения свойства;
  2.  организуется свойство Property для связи этой переменной с внешним миром.

 Если же эта переменная вам внутри класса не нужна, то вы можете обойтись и без нее и вычислять значение свойства прямо в теле свойства в части Get - End Get.

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

Для этого превращаем поле Владелец в модульную переменную:

Private Владелец As String

Тогда  свойство Владелец_участка будет следующим:

Public WriteOnly Property Владелец_участка( ) As String

   Set (ByVal Value As String) 

        Владелец = Value

   End Set

End Property

 

Теперь рассмотрим  конструкторы (специальные процедуры с именем New). Обратите внимание, что эти процедуры могут выполняться автоматически при создании объекта.  

Для чего же нужен New? Для того же, для чего, и процедура Form1_Load( ) (ведь форма загружалась при отсутствии этой процедуры), а именно для того, чтобы произвести некоторые действия, которые программист считает нужным произвести в момент создания объекта из класса. Обычно это присвоение начальных значений переменным, открытие нужных файлов и т. п.

Пример 5.3.4-5. Использование конструктора для присваивания значения.

Рассмотрим использование конструктора для присвоения в каждом объекте нужного значения полю Номер_участка. Ранее оно присваивалось в модуле формы, что противоречит принципу инкапсуляции.

Уберем из кода формы строку,

Участки(k).Номер_участка = k

а  вместо этого дополним наш класс:

Public Номер_участка As Integer

Private Shared Число_созданных_объектов As Integer = 0

Public Sub New()

    Число_созданных_объектов = Число_созданных_объектов + 1

    Номер_участка = Число_созданных_объектов

End Sub

При создании очередного участка увеличивается  на единицу статическая переменная класса Число_созданных_объектов. Поэтому к моменту создания очередного участка эта переменная автоматически приобретает нужное значение, которое оператором:

Номер_участка = Число_созданных_объектов

придается полю Номер_участка.

Конструктор, как и всякая процедура, может иметь параметры. Обычно параметры используются для задания начальных значений переменным, полям и свойствам класса. Зададим через параметры имя владельца, длину, ширину участка и высоту забора.

В учебных целях сделаем переменную Ширина модульной переменой.

Public Class Участок

 

 Public Владелец As String 

 Private Длина As Integer

 Public Property Длина_участка() As Integer 

     Get

       Return Длина 

     End Get

      

     Set (ByVal Value As Integer) 

        If Value < 500 Then

          Длина = Value  

        Else

           MsgBox("Cлишком длинный участок") : Длина = 0

        End If

     End Set

 End Property

 Private        Ширина As Integer

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

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

 Private        Периметр As Integer

 Public         Номер_участка As Integer 

 Private Shared Число_созданных_объектов  As Integer = 0

 Public Sub New (ByVal Влад As String, ByVal Дл As Integer, _

                 ByVal Шир As Integer, ByVal Выс As Integer)

     Владелец = Влад

     Длина_участка = Дл

     Ширина = Шир

     Высота_забора = Выc

     Число_созданных_объектов = Число_созданных_объектов +1

     Номер_участка = Число_созданных_объектов 

 End Sub

 Private Sub Вычисляем_периметр() 

     Периметр = 2 * (Длина + Ширина)

 End Sub

  Private Function Площадь_забора() As Integer

      Вычисляем_периметр()

    Return Периметр * Высота_забора 

 End Function

 Public Function Расход_краски() As Integer

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

 End Function 

End Class

‘Для проверки работы конструктора необходимо нажать  на кнопку:

Dim Участки(100) As Участок

Private Sub Button1_Click(ByVal sender As System.Object, _

                ByVal e As System.EventArgs) Handles Button1.Click 

  Dim SS As String = ""

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

  Участки(1) = New Участок("Иванов", 5,4,2)

  SS=SS & (Учacтки(1).Pacxoд_кpacки)

  Участки(2) = New Участок("Петров", 800,5,3)

  SS = SS & Учacток(2).Pacxoд_кpacки)

  TextBox1.Text=SS

End Sub

 

Как видите, при помощи параметров конструктора мы можем задать значения поля Владелец и Высота_забора свойству Длина_участка, а также добраться извне до модульной переменной Ширина, невидимой снаружи.


5.3.5.  Задачи для самостоятельного решения по теме  
«Средства объектно-ориентированного программирования в  Visual Basic»

  1.  В n разных  школах г. Москвы  (номера  школ известны)  проведен анонимный опрос  m   школьников 6 классов  (числа n и m известны).  Школьникам задавался вопрос,  курят ли они.  В опросе  участвовали  как мальчики, так  и девочки. Результаты  опроса поступали  неупорядоченными  по школам.   Определить школы  с    максимальным процентом курящих отдельно по мальчикам и девочкам. Предусмотреть проверку правильности  ввода   информации.
  2.  Известны фамилии n сотрудников больницы (n - заданное число). Сотрудники работают по индивидуальному графику (1-й день - утро, 2-й день - вечер, 3-й день - выходной). В первое число месяца известно, в какую смену работает каждый сотрудник или имеет выходной. Составить алгоритм и программу, которые позволяют на любое заданное число месяца напечатать пронумерованный список сотрудников, имеющих выходной. Считать, что в месяце 30 дней.
  3.  Известны названия m предприятий города, производящие по n наименований различных изделий, для которых известны  количества их выпуска в год. Составить алгоритм и программу, которые  по наименованию изделия определяют название предприятия, производящего максимальное количество этого изделия, а также  печатают список предприятий, на которых это изделие производится, располагая названия этих предприятий в порядке убывания объема  выпуска данного изделия.
  4.  Список n рабочих цеха (n – заданное число) содержит следующие сведения о каждом: фамилия, числовой номер бригады, зарплата. Список не имеет определенной упорядоченности. Составить алгоритм и программу, которые выводят на экран списки рабочих по бригадам, располагая фамилии в порядке убывания зарплаты, и, кроме того, определяют и печатают значения средних зарплат по бригадам.
  5.  Пароходство  владеет    n  пассажирскими теплоходами (n и названия теплоходов заданы),  каждый из которых   имеет   каюты люкс на 1 и 2 палубах,  первого  класса на 2 и 3 палубах,  второго класса на 3 и 4 палубах  и третьего класса на 3 и 4 палубах. На каждом из теплоходов каюта  может быть занята,  забронирована или свободна. Составить алгоритм и программу для вывода по указанному пользователем теплоходу отдельно информации о количестве свободных кают и отдельно информации о количестве забронированных кают. Информацию выдать по каждой из палуб в порядке возрастания их номеров с указанием класса кают.
  6.  В течение месяца (30 дней) абоненты международной телефонной сети производили переговоры с m странами. Каждая страна имеет свой код и тариф за 1 мин.  Составить алгоритм и программу, которые печатают счета абонентам, в которых указывается телефон абонента, код страны, количество минут, стоимость каждого разговора и итог за месяц.  В общем списке абоненты представлены телефонными номерами, а для каждого разговора известна его продолжительность.
  7.  В чемпионате  по футболу приняло участие n команд (названия команд известны). Составить алгоритм и программу, которые определяют 4 команды, показавшие лучшие результаты, если известен счет каждого матча. При равных условиях лучшей считается команда, у которой разность между забитыми и пропущенными мячами лучше.
  8.  В течение года (12 месяцев) отслеживалось изменение курсов n  валют. Известны названия валют и их курс по отношению к рублю на последнее число каждого месяца. Составить алгоритм и программу, которые за каждый квартал определяют валюты, у которых  наблюдался наибольший и наименьший рост относительно среднего квартального курса данной валюты.

  1.  Имеются сведения о доходах пяти магазинов по дням в течение одного месяцамесяце 30 дней). Составить алгоритм и программу, которые для каждого магазина определяют числа месяца и соответствующие им дни недели с минимальным доходом, учитывая, что по субботам и воскресеньям магазины закрыты, а первое число месяца - вторник.
  2.  В отделе кадров предприятия имеется список сведений о n сотрудниках. О каждом сотруднике известно: фамилия (в списке фамилии расположены  по алфавиту), номер отдела, должность, оклад и стаж работы. Составить алгоритм и программу, которые выводят списки фамилий сотрудников по отделам с указанием занимаемой должности,  оклада и стажа.
  3.  Каждый из 5пяти цехов завода составляет ежемесячную заявку на приобретение по M разных комплектующих деталей. В заявке указаны: наименование детали, требуемое количество и завод-изготовитель (поставщик). Составить алгоритм и программу, которые выводят сводные списки заказов деталей для рассылки по поставщикам, в которых указаны наименования деталей с указанием общего количества требуемых деталей.
  4.  В бюро по трудоустройству имеются сведения о N вакансиях на предприятиях города. О каждом  вакантном месте известно: название предприятия, должность, оклад, требуемое образование (высшее или среднее), предельный возраст. Составить алгоритм и программу, которые  по данным об образовании и возрасте печатают список вакансий, располагая их в порядке убывания окладов.
  5.  В префектуре имеются сведения о потребностях в улучшении жилищных условий 1500 семей. О каждой семье известно, на квартиру из скольких комнат она претендует. Составить алгоритм и программу, которые печатают список семей, получивших квартиры в новом доме, и список семей, оставшихся в очереди, если известно, что в  доме 100 квартир, из которых 30 однокомнатных, 40  двухкомнатных и 30  трехкомнатных.
  6.  Имеются сведения об урожаях зерна в  n регионах России за m лет.  Составить алгоритм и программу, которые  определяют самый урожайный и самый неурожайный годы и для каждого года печатают список регионов в порядке убывания полученного в них урожая.
  7.  Список участниц конкурса красоты содержит 12 фамилий. Каждый из 200 опрошенных называет трех претенденток, и определяет каждой из них одно из первых 3-х мест. Вывести на экран фамилию участницы, набравшей наибольшее число первых мест. Если таких участниц несколько, то вывести фамилии всех участниц.     
  8.  В типографии заказано n визитных карточек. Составить алгоритм и программу, которые определяют стоимость заказа, если первые 100 визиток стоят 5 руб. за штуку, а стоимость каждой последующей карточки   уменьшается соответственно на 1 коп.  
  9.  Список участниц конкурса красоты содержит 12 фамилий. Каждый из 200 опрошенных называет трех претенденток и определяет каждой из них одно из первых 3-х мест. Вывести на экран фамилию участницы, набравшей наибольшее число первых мест. Если таких участниц несколько, то вывести фамилии всех участниц.                                                                        
  10.  Для  каждого из  20 классов школы известно, сколько в них мальчиков и сколько девочек. Составить алгоритм и программу, которые выводят номера классов по убыванию процентного состава мальчиков и определяют процент девочек и мальчиков по школе в целом.                                             
  11.  В доме проводится остекление окон. Количество квартир в доме и количество комнат в каждой квартире (1, 2 или 3) известно. Составить схему алгоритма и программу, которые определяют, сколько м2  стекла надо закупить и общую стоимость стекла, если в трехкомнатной квартире площадь окон составляет 10 м2, в двухкомнатной – 7 м2, в однокомнатной – 5 м2, а стоимость 1 м2 стекла 200 руб.
  12.  Составить алгоритм и программу, которые выводят список фамилий школьников по убыванию их среднего балла за год, а также определяют процент отличников (все отметки 5) и процент хорошистов (отметки 5 и 4), если для каждого из 25 школьников известны итоговые оценки по 15 предметам.
  13.  Объем файла, подлежащего архивации, составляет S мегабайт. При архивации объем файла уменьшается: программой ZIP – на 30%, а программой ARJ – на 25%, после чего архив разбивается на дискеты по 1,44 мегабайт. Составить алгоритм и программу, определяющую необходимое количество дискет для архивации файла заданного объема в зависимости от типа выбранной программы архивации (тип программы архивации вводится).
  14.  Известны сведения о багаже авиапассажиров одного рейса (багаж характеризуется фамилией пассажира,  количеством вещей и общим весом). Составить алгоритм и программу, которые определяют средний вес багажа авиапассажира (в самолете занято n мест, но не все пассажиры имеют багаж), подсчитывают число пассажиров, у которых отсутствует багаж, и число пассажиров, у которых вес багажа превосходит средний вес, а также напечатают список фамилий пассажиров, у которых вес багажа превысил норму – S кг.
  15.  Имеется n партий микросхем одного вида. Из каждой партии отобрали  m микросхем и раздали для контроля работникам отдела в произвольном порядке, которые определяли ее годность или негодность. Для того чтобы вся партия была забракована, достаточно, чтобы из m выбранных микросхем были забракованы k. Составить алгоритм и программу, которые по итогам контроля определяют количество негодных микросхем в каждой партии и количество забракованных партий.  
  16. Каждое из n швейных предприятий области специализируется на выпуске традиционных для данного предприятия m видах швейной продукции. Составить алгоритм и программу, позволяющие для каждого вида продукции определить предприятия (их номера), выпускающие данный вид  продукции.
  17.  Для обслуживания международной конференции необходимо отобрать бригаду переводчиков, обладающих навыками синхронного перевода. В оргкомитет поступили предложения от М переводчиков, каждый из которых владеет двумя языками. Составить алгоритм и программу, которые производят отбор переводчиков, руководствуясь минимизацией расходуемых средств, если в бригаде обязательно должны быть по два переводчика с каждого из пяти заявленных на конференцию языков.                                   
  18.  Ежедневно частное предприятие по быстрой доставке почты имеет n заказов, каждый заказ характеризовался стоимостью Ti и директивным сроком доставки Li. За превышения директивного срока предприятие выплачивало из стоимости заказа штраф, размеры которого линейно пропорциональны (с коэффициентом b) количеству просроченных часов. Досрочное выполнение заказа поощрялось премией в размере а% от стоимости заказа. Составить алгоритм и программу расчета дохода, полученного предприятием  за месяц, если известны реальные сроки выполнения каждого из n заказов в каждый из 30 дней месяца.
  19.  Агент 007, отправляясь на задание, формирует багаж необходимых спецсредств, каждое их которых характеризуется определенной убойной силой и объемом. В целях конспирации объем дипломатического багажа ограничен. Составить алгоритм и программу, которые помогут сформировать багаж агента, т.е. производят выбор из М вариантов каждого средства то средство, которое обладает максимальной убойной силой, при этом учитывают, что суммарный объем всех выбранных средств не должен превышать заданный (S).    
  20.  При производстве радиоприемника используется n наименований элементов. На складе имеется по M элементов каждого типа, каждый из которых характеризуется эффективностью, стоимостью и весом. Составить алгоритм и программу, которые позволяют выбрать самую эффективную элементную базу, вычислив при этом стоимость и вес составляющих ее элементов.    

  1.  При расчете Единого социального налога (ЕСН) придерживаются следующей схемы: если сумма дохода нарастающим итогом за расчетный период не превышает  N руб., то на эту сумму начисляют k1% налога, если превышает, то на сумму N руб. начисляют k1% налога, а на сумму превышения  начисляют k2% налога(k1>k2). Составить алгоритм и программу, которые производят начисления ЕСН за год для l сотрудников предприятия, если имеются списки сотрудников с указанием сумм доходов по месяцам года, и печатают фамилии тех сотрудников, на доходы которых сумма налога превысила S руб.
  2.  В театральную кассу поступило n заявок (n задано) от школ города. Каждая заявка содержит название одного спектакля и необходимое количество билетов. Составить алгоритм и программу, которые на основании этих данных определяют популярность каждого спектакля и печатают их названия в порядке убывания количества заказанных на них билетов.     
  3.  Кондитерская фабрика получила заказ на изготовление l тортов. Каждый торт изготавливается из n ингредиентов. На складе имеется по m видов каждого ингредиента, которые характеризуются сортом и ценой. Составить алгоритм и программу, которые определяют общую стоимость заказа, если для его выполнения были выбраны самые дорогие ингредиенты, и печатают список выбранных ингредиентов с указанием сорта и цены, обозначив ингредиенты номерами. Стоимость изготовления одного торта S руб.
  4.  Фирма по ремонту квартир получила n заказов, каждый их которых характеризуется стоимостью Ti и сроком его выполнения Li. За превышение срока выполнения стоимость заказа уменьшается на величину, пропорциональную количеству просроченных дней, а досрочное выполнение заказа поощряется премией в размере а% от стоимости заказа. Составить алгоритм и программу, которые определяют сумму, полученную фирмой за выполнение всех n заказов, если реальные сроки их выполнения известны.
  5.  При установленном счетчике расхода воды тариф составляет 35 коп. за один литр. При отсутствии счетчика, плата за воду в месяц для одной семьи составляет  150 руб.  Составить алгоритм и программу, которые по известным  данным о ежедневном потреблении воды (в литрах) одной семьей за 30 дней месяца, определяют, что выгоднее – оплата по счетчику или без счетчика, а также  среднесуточный расход воды.                              
  6.  Для каждого из n студентов (фамилии известны)  в архиве хранятся сведения о 60 оценках, полученных им за все время обучения в институте. Составить алгоритм и программу, определяющие, имеет ли студент право получить «красный диплом», если на «красный диплом» нельзя иметь ни одной тройки, а четверок – не более 10%. Вывести на экран список фамилий студентов с указанием его средней оценки, а также список студентов, которые имеют право получить «красный диплом».                        
  7.  Кабельный завод выпускает N видов кабелей. Каждый вид кабеля характеризуется маркой и стоимостью его метра. К заводу обратилось M заказчиков на поставку определенного количества каждого вида кабеля. Составить алгоритм и программу, которые для каждой марки кабеля определяют общее количество заказа, а также печатают список предприятий-заказчиков с указанием суммы договора, располагая названия предприятий  в порядке убывания суммы договора.
  8.  При медицинском обследовании у N учащихся СПТУ был взят анализ крови на сахар. О каждом ученике известно: фамилия, группа и результат анализа. Составить алгоритм и программу,  которые печатают по группам списки учащихся с их результатами анализа, а также отдельный список учащихся, у которых уровень сахара в крови превышает норму, расположив фамилии в списке в порядке убывания результата анализа, считая, что допустимая норма уровня сахара в крови заданная величина.


  1. Создать DLL с классом Point, описывающим точку на плоскости, заданную декартовыми и полярными координатами. Среди методов класса Point предусмотреть метод Distance, вычисляющий расстояние до заданной точки. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с классом Point.
  2. Создать DLL с классами Point и Line, описывающими точку и линию на плоскости. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Line предусмотреть метод, определяющий принадлежность заданной точки линии.
  3. Создать DLL с классами Point и Square, описывающими точку и квадрат на плоскости со сторонами, параллельными осям координат. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Square предусмотреть метод, определяющий принадлежность заданной точки квадрату.
  4. Создать DLL с классами Point и Circle, описывающими точку и круг на плоскости. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Circle предусмотреть метод, определяющий принадлежность заданной точки кругу.
  5. Создать DLL с классами Point и Rectangle, описывающими точку и прямоугольник на плоскости со сторонами, параллельными осям координат. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Rectangle предусмотреть метод, определяющий принадлежность заданной точки прямоугольнику.
  6. Создать DLL с классами Point и Rhomb, описывающими точку и ромб на плоскости с осями, параллельными осям координат. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Rhomb предусмотреть метод, определяющий принадлежность заданной точки ромбу.
  7. Создать DLL с классами Point и Tetragon, описывающими точку и четырехугольник на плоскости. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Tetragon предусмотреть метод, определяющий принадлежность заданной точки четырехугольнику.
  8. Создать DLL с классами Point и Triangle, описывающими точку и треугольник на плоскости. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL. Среди методов класса Triangle предусмотреть метод, определяющий принадлежность заданной точки треугольнику.
  9. Создать DLL с классами Account и Accounts, описывающими счет в банке и множество счетов клиентов, хранящихся в файле. Построить Windows-проект, предоставляющий пользователю интерфейс для работы с DLL.


Практикум

  1.  Создать класс  Point, разработав следующие элементы класса:
  2.  Поля:
  3.  int x, y;
  4.  Конструкторы, позволяющие создать экземпляр класса:
  5.  с нулевыми координатами;
  6.   с заданными координатами.
  7.  Методы, позволяющие:
  8.  вывести координаты точки на экран;
  9.  рассчитать расстояние от начала координат до точки;
  10.  переместить точку на плоскости на вектор (a, b).
  11.  Свойства:
  12.  получить-установить координаты точки (доступное для чтений и записи);
  13.  позволяющие умножить координаты точки на скаляр (доступное только для записи).

  1.  Создать класс Triangle, разработав следующие элементы класса:
  2.  Поля:
  3.  int a, b, c;
  4.  Конструктор, позволяющий создать экземпляр класса  с заданными длинами сторон.
  5.  Методы, позволяющие:
  6.  вывести длины сторон треугольника на экран;
  7.  расчитать периметр треугольника;
  8.  расчитать площадь треугольника.
  9.  Свойства:
  10.  позволяющее получить-установить длины сторон треугольника (доступное для чтения и записи);
  11.  позволяющее установить, существует ли треугольник с данными длинами сторон (доступное только для чтения).

  1.  Создать класс Rectangle, разработав следующие элементы класса:
  2.  Поля:
  3.  int a, b;
  4.   Конструктор, позволяющий создать экземпляр класса  с заданными длинами сторон.
  5.  Методы, позволяющие:
  6.  вывести длины сторон прямоугольника на экран;
  7.  расчитать периметр прямоугольника;
  8.  расчитать площадь прямоугольника.
  9.  Свойства:
  10.  получить-установить длины сторон прямоугольника (доступное для чтения и записи);
  11.  позволяющее установить, является ли данный прямоугольник квадратом (доступное только для чтения).

  1.  Создать класс Money, разработав следующие элементы класса:
  2.  Поля:
  3.  int first;//номинал купюры
  4.  int second; //количество купюр
  5.  Конструктор, позволяющий создать экземпляр класса  с заданными значениям полей.
  6.  Методы, позволяющие:
  7.  вывести номинал и количество купюр;
  8.  определить, хватит ли денежных средств на покупку товара на сумму N рублей.
  9.  определить, сколько шт товара стоимости n рублей можно купить на имеющиеся денежные средства.
  10.  Свойства:
  11.  позволяющее получить-установить значение полей (доступное для чтения и записи);
  12.  позволяющее расчитатать сумму денег (доступное только для чтения).

  1.  Создать класс для работы с одномерным массивом целых чисел. Разработать следующие элементы класса:

a.  Поля:

  1.  int [] IntArray;
  2.  int n.

b. Конструктор, позволяющий создать массив размерности n.

c. Методы, позволяющие:

  1.  ввести элементы массива с клавиатуры;
  2.  вывести элементы массива на экран;
  3.  отсортировать элементы массива в порядке возрастания.

d. Свойства:

  1.  возвращающее размерность массива (доступное только для чтения);
  2.  позволяющее домножить все элементы массива на скаляр (доступное только для записи).

  1.  Создать класс для работы с двумерным массивом целых чисел. Разработать следующие элементы класса:
  2.  Поля:
  3.  int [,] IntArray;
  4.  int n.
  5.  Конструктор, позволяющий создать массив размерности n×n.
  6.  Методы, позволяющие:
  7.  ввести элементы массива с клавиатуры;
  8.  вывести элементы массива на экран;
  9.  вычислить сумму элеметов i-того столбца.
  10.  Свойства:
  11.  позволяющее вычислить количество нулевых элементов в массиве (доступное только для чтения);
  12.  позволяющее установить значение всех элементы главной диагонали массива равное скаляру (доступное только для записи).

  1.  Создать класс для работы с двумерным массивом вещественных чисел. Разработать следующие элементы класса:
  2.  Поля:
  3.  double [][] DoubelArray;
  4.  int n, m.
  5.  Конструктор, позволяющий создать массив размерности n×m.
  6.  Методы, позволяющие:
  7.  ввести элементы массива с клавиатуры;
  8.  вывести элементы массива на экран;
  9.  отсортировать элементы каждой строки массива в порядке убывания.
  10.  Свойства:
  11.  возвращающее общее количество элементов в массиве (доступное только для чтения);
  12.  позволяющее увеличить значение всех элементов массива на скаляр (доступное только для записи).

  1.  Создать класс для работы сo строками. Разработать следующие элементы класса:
  2.  Поля:
  3.  StringBuilder Line;
  4.  int n.
  5.  Конструктор, позволяющий создать строку из n символов.
  6.  Методы, позволяющие:
  7.  подсчитать количество пробелов в строке;
  8.  заменить в строке все прописные символы на строчные;
  9.  удалить из строки все знаки препинания.
  10.  Свойства:
  11.  возвращающее общее количество элементов в строке (доступное только для чтения);
  12.  позволяющее установить значение поля, в соответствии с введенным значением строки с клавиатуры, а также получить значение данного поля (доступно для чтения и записи)

  1.  Создать класс для работы с регулярными выражениями. Разработать следующие элементы класса:
  2.  Поля:
  3.  Regex r;
  4.  string text;
  5.  Методы, позволяющие:
  6.  определить, содержит ли текст фрагменты, соответствующие шаблону поля;
  7.  вывести на экран все фрагменты текста, соответствующие шаблону поля;
  8.  удалить из текста все фрагменты, соответствующие шаблону поля;

Свойства:

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

  1.  Создать класс для работы с датой. Разработать следующие элементы класса:
  2.  Поле DataTime data.
  3.  Конструкторы, позволяющие установить:
  4.  заданную дату
  5.  дату 1.01.2009
  6.  Методы, позволяющие:
  7.  вычислить дату предыдущего дня;
  8.  вычислить дату следующего дня;
  9.  определить сколько дней осталось до конца месяца.
  10.  Свойства:
  11.  позволяющее установить или получить значение поле класса (доступно для чтения и записи)
  12.  позволяющее определить год высокосным (доступно только для чтения)


5.3.6.  Тестовые задания по теме  

«Средства объектно-ориентированного программирования в  Visual Basic»

Класс имеет

  1. только один конструктор;
  2. только конструктор по умолчанию;
  3. не более одного статического конструктора;
  4. не более одного закрытого конструктора;
  5. несколько конструкторов с одинаковой сигнатурой.

Отметьте истинные высказывания:

  1. статические методы класса могут вызывать любые методы класса;
  2. все конструкторы класса вызываются только при выполнении операции new;
  3. свойства задаются для закрытых полей класса;
  4. каждый объект содержит набор из всех полей, определенных в классе.

Свойство класса:

  1. может иметь атрибут доступа private;
  2. может включать методы get и set;
  3. включает только один из методов get или set;
  4. позволяет реализовать различные стратегии доступа к закрытым полям класса;
  5. обязательно должно быть указано для каждого закрытого поля класса.

Объекты класса Rational могут быть созданы в клиентском классе:

  1. конструктором по умолчанию;
  2. конструктором с аргументами;
  3. закрытым конструктором;
  4. статическим конструктором.

Отметьте истинные высказывания:

  1. любые методы класса могут вызывать статические методы;
  2. конструкторы класса вызываются автоматически;
  3. у класса может быть только один индексатор
  4. класс не может иметь закрытых методов.

Поля класса:

  1. могут иметь любой из модификаторов доступа: public, private, protected, internal;
  2. могут иметь модификатор static;
  3. обычно закрываются;
  4. закрытые поля доступны методам класса.

Тело класса может содержать описание:

  1. полей;
  2. методов;
  3. классов;
  4. интерфейсов;
  5. пространств имен;
  6. событий.

Отметьте истинные высказывания:

  1. статическое поле класса доступно в любом методе класса;
  2. статический конструктор класса вызывается автоматически;
  3. у класса может быть задано несколько свойств;
  4. у класса может быть задано несколько индексаторов;
  5. у класса может быть определено несколько операций.

Пусть p1, p2, p3 – переменные класса Rational. Отметьте правильно построенные конструкции:

  1. if(p1 != p2) p3 = p1+p2;
  2. p3 = p1+ p2 +1;
  3.  p3 =(Rational.One + Rational.One)* p2 +p1;
  4. p3 +=Rational.One;
  5. p3++.




 

А также другие работы, которые могут Вас заинтересовать

31478. Аналіз майна підприємства та оцінка матеріальних активів та фінансових інвестицій підприємства 141 KB
  Оцінка матеріальних активів основних засобів та фінансових інвестицій. Рекомендована література: Дидактична мета заняття: сформувати у студентів сучасне економічне мислення щодо оцінки матеріальних активів основних засобів та фінансових інвестицій дати теоретичні уявлення щодо класифікації та порядку розрахунку й методів оцінки показників що характеризують стан і ефективність використання майна підприємства. Оцінка матеріальних активів основних засобів...
31479. Аналіз оборотних активів та аналіз оборотного капіталу 108.5 KB
  Аналіз оборотних активів Лекція 7 2 год. Мета заняття: ознайомити студентів із завданнями аналізу оборотного капіталу підприємства поглибити їхні знання з питань аналізу обертання активів підприємства та ефективності їх використання розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. Основні показники оцінки стану та ефективності використання оборотних активів підприємства. Рекомендована література: 2 7 8 11 12 13 14 15 16 17 21 22 23 24 29 30 37 38...
31480. Аналіз оборотних активів 84 KB
  Мета заняття: ознайомити студентів із методикою аналізу власних оборотних засобів дебіторської та кредиторської заборгованості поглибити їхні знання з питань аналізу виробничих запасів та готової продукції розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. Аналіз стану та ефективності використання виробничих запасів та готової продукції на підприємстві. Завдання лекції: ознайомитись з методами аналізу наявності власних оборотних коштів; дати теоретичні та...
31481. Аналіз джерел формування капіталу підприємства 108.5 KB
  Аналіз джерел формування капіталу підприємства Лекція 9 2 год. Мета заняття: ознайомити студентів із значенням та методами аналізу капіталу підприємства поглибити їхні знання з питань оцінки складу і динаміки джерел формування капіталу методики оцінки стану та ефективності використання капіталу розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Значення і методи аналізу капіталу підприємства. Аналіз наявності складу і динаміки джерел формування капіталу.
31482. Аналіз грошових потоків, оцінка руху грошових коштів 164 KB
  Аналіз грошових потоків Лекція 10 2 год. Мета заняття: ознайомити студентів із методами оцінки руху грошових коштів поглибити їхні знання з питань необхідності та мети використання грошових потоків на підприємстві аналізом грошових коштів у розрізі видів діяльності розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Поняття види та значення грошових потоків для підприємства. Аналіз грошових коштів від основної інвестиційної та фінансової діяльності...
31483. Аналіз грошових потоків, оцінка грошових надходжень 121.5 KB
  Аналіз грошових потоків Лекція 11 2 год. Мета заняття: ознайомити студентів із балансовим методом оцінки грошових надходжень методикою аналізу грошових потоків із застосуванням системи коефіцієнтів поглибити їхні знання стосовно методів розрахунку обертання грошових потоків на підприємстві та їх ефективності розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Оцінка динаміки грошових потоків по періодах. Балансовий метод оцінки грошових надходжень.
31484. Аналіз ліквідності і платоспроможності підприємства 243.5 KB
  Аналіз ліквідності і платоспроможності підприємства Лекція 12 2 год. Мета заняття: ознайомити студентів та поглибити їхні знання з питань необхідності та методики аналізу показників ліквідності і платоспроможності підприємства розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Поняття ліквідності і платоспроможності підприємства. Основні показники ліквідності підприємства – порядок їх розрахунку та методи оцінки.
31485. Аналіз фінансової стійкості підприємства 104 KB
  Аналіз фінансової стійкості підприємства Лекція 13 2 год. Мета заняття: ознайомити студентів та поглибити їхні знання з питань сутності фінансової стійкості підприємства порядку оцінки та визначення основних показників і типів фінансової стійкості розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Сутність фінансової стабільності та стійкості підприємства. Дидактична мета заняття: сформувати у студентів сучасне економічне мислення щодо поняття фінансової...
31486. Аналіз кредитоспроможності підприємства 153 KB
  Аналіз кредитоспроможності підприємства Лекція 14 2 год. Мета заняття: ознайомити студентів із класифікаційними моделями аналізу кредитоспроможності методикою оцінки кредитоспроможності позичальниківюридичних осіб згідно з методикою НБУ та методикою комплексного аналізу кредитоспроможності поглибити їхні знання щодо сутності кредитоспроможності підприємства розвивати логічне мислення студентів привчати творчо оперувати набутими знаннями виховувати інтерес до обраної професії. ПЛАН Сутність кредитоспроможності підприємства....