Тема Архитектура и возможности семейства языков высокого уровня



Скачать 135.43 Kb.
Дата03.05.2016
Размер135.43 Kb.

МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ

INTERNATIONAL BANKING INSTITUTE

Тема 7. Архитектура и возможности семейства языков высокого уровня


Цель

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



Задачи

  1. Рассмотреть три основных принципа объектно-ориентированных языков программирования.

  2. Описать структуру классов в объектно-ориентированных языках программирования на примере Visual Basic.NET.

  3. Выполнить реализацию свойств класса в VB.NET.

Оглавление

Тема 7. Архитектура и возможности семейства языков высокого уровня 1

Базовые принципы объектно-ориентированного программирования 1

Определение классов в Visual Basic.NET 4

Свойства классов в Visual Basic.NET 6

Выводы 11

Вопросы для самопроверки 11

Литература 12



Базовые принципы объектно-ориентированного программирования


Язык Visual Basic.NET можно считать новым членом сообщества объектно-ориентированных языков программирования, к самым распространенным из которых относятся Java, C++, Object Pascal и (с некоторыми допущениями) Visual Basic 6.0 (VB является языком, умеющим работать с объектами). В любом объектно-ориентированном языке программирования обязательно реализованы три важнейших (базовых) принципа объектно-ориентированного программирования:

  • Инкапсуляция: как объекты прячут свое внутреннее устройство;

  • Наследование: как в этом языке поддерживается повторное использование кода;

  • Полиморфизм: как в этом языке реализована поддержка выполнения нужного действия в зависимости от типа передаваемого объекта?

Все базовые принципы в полной мере реализованы в языках, принадлежащих к платформе .NET, в том числе и в языке Visual Basic.NET.

ИНКАПСУЛЯЦИЯ

Первый «столп» объектно-ориентированного программирования – это инкапсуляция. Так называется способность прятать детали реализации объектов от пользователей этих объектов. Например, предположим, что мы создали класс с именем DBReader (для работы с базой данных); в классе определено два главных метода: Open() и Close().

Класс DBReader скрывает за счет инкапсуляции подробности открытия и закрытия баз данных



Dim f As New DBReader

f.Open("C:\foo.mdb")

Выполняем с базой данных нужные нам действия

f.Close()

Наш класс DBReader инкапсулирует внутренние подробности того, как именно он обнаруживает, загружает, выполняет операции и, в конце концов, закрывает файл данных.

За счет инкапсуляции программирование становится проще: вам нет необходимости беспокоиться об огромном количестве строк кода, которые выполняют свою задачу, подробности, скрыты от вас. Все, что вам необходимо – создать экземпляр нужного класса и передать ему необходимые сообщения (типа «открыть файл с именем foo.mdb»).

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

НАСЛЕДОВАНИЕ: отношения «быть» и «иметь»

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

Простой пример реализации такого подхода представлен на рис. 7.1. Как вы помните, на вершине любой иерархии в .NET всегда находится базовый класс Object. В нашей ситуации возможности этого класса вначале дополняются возможностями, привнесенными классом Shape. Речь идет о свойствах, методах и событиях, которые являются общими для всех геометрических фигур (shape). Класс Hexagon (шестиугольник), производный от Shape, дополняет возможности предыдущих двух базовых классов своими собственными уникальными свойствами.



Рис. 7.1. Отношение «быть»

Диаграмму классов, представленную на рис. 7.1, можно прочесть следующим образом: «Шестиугольник есть геометрическая фигура, которая есть объект». Когда ваши классы связываются друг с другом отношениями наследования, это означает, что вы устанавливаете между ними отношение типа «быть» (is-a). Такой тип отношения называется также классическим наследованием.

ПОЛИМОРФИЗМ

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

Для примера мы вновь обратимся к нашей иерархии геометрических фигур. Предположим, что в классе Shape (геометрическая фигура) определена функция Draw() – рисование, которая не принимает параметров и ничего не возвращает. Поскольку геометрические фигуры бывают разными, и каждый тип фигуры потребует изображать своим собственным уникальным способом, скорее всего, нам потребуется в производных классах (таких как Hexagon – шестиугольник и Circle – окружность) создать свой собственный метод Draw(), заместив им метод Draw() базового класса (рис. 7.2).

Классический полиморфизм позволяет определять возможности всех производных классов при создании базового класса. Например, в нашем случае вы можете быть уверены, что метод Draw() в том или ином варианте присутствует в любом классе, производном от Shape. К достоинствам классического полиморфизма можно отнести также и то, что во многих ситуациях вы сможете избежать создания повторяющихся методов для выполнения схожих операций (типа DrawCircle(), DrawRectangle(), DrawHexagon() и так далее).

Рис. 7.2. Полиморфизм


Определение классов в Visual Basic.NET


Мы используем ключевое слово Class для определения класса. Класс может содержать данные и методы, выполняющие действия. В следующей таблице представлены виды-членов, которые мы можем определить в классе:

Вид данных-членов

Описание

Переменная

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

Свойство

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

Константа

Константа – это значение, доступное только для чтения и используемое всеми объектами класса.

Событие

Событие – это сообщение, которое объект может послать другим заинтересованным в этом объектам. В .NET Framework мы используем терминологию «источник события» для обозначения объекта, который может генерировать событие, и «получатель события» для обозначения объекта, который принимает события.

Вид функции-члена

Описание

Метод

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

Конструктор

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

Завершающий метод

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

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

Class MyClass1

End Class

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

Public Class MyClass2

End Class

Класс MyClass2 явным образом объявлен доступным для всех сборок.

Friend Class MyClass3

End Class

Класс MyClass3 виден в текущей сборке, но не виден извне.

Private Class MyClass4

End Class

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





Свойства классов в Visual Basic.NET


Свойство ведет себя, с точки зрения программиста, использующего класс, как порция данных класса. Пользователи класса могут обращаться к имени свойства напрямую, как будто класс на самом деле имеет элемент с таким именем. Однако внутри класса свойство реализуется как пара процедур свойства: процедура Get свойства, получающая значение свойства, и процедура Set свойства, устанавливающая значение свойства. Процедуры свойства выполняют всю обработку, требуемую для получения и задания значения свойства.

Свойства являются важной частью разработки нашего класса. Например, следующая диаграмма показывает небольшой фрагмент модели объекта, представляющего человека, работающего в компании. Используется нотация UML (Unified Modeling Language) (рис. 7.3).



Рис. 7.3. Диаграмма классов

Класс Person имеет два атрибута с именами Name и Age. Когда мы реализуем этот класс в VB.NET мы должны решить, как представить Name и Age в нашем коде. Одним из вариантов может быть определение Name и Age как Private-полей класса Person; однако это не позволит обращаться к информации ниоткуда, кроме самого класса. Можно объявить Name и Age как Public-поля, но тогда нарушается принцип инкапсуляции для класса Person: открывается доступ к данным, которые при таком объявлении могут быть прочитаны и изменены любой другой частью программы – сокрытие данных полностью разрушено.

Свойства класса позволяют решить эту проблему. Свойства позволяют предоставлять данные клиентскому коду и, в то же время, сохранять инкапсуляцию того, как данные представлены внутри класса. Например, мы можем написать проверочный код в процедуре Set свойства для того, чтобы быть уверенными в том, что пользователь не присвоит свойству недопустимое значение. Аналогично, мы можем выполнить вычисления в процедуре Get свойства для пересчета значения свойства по требованию.

Мы можем опустить процедуру Get или Set для свойства:


  • Если мы опускаем процедуру Set свойства и используем ключевое слово ReadOnly при описании свойства, то, очевидно, оно будет свойством только для чтения. Это может быть полезно для свойств, которые должны быть пересчитаны каждый раз, когда они используются, например, число дней, которые сотрудник работает в компании. Другим случаем использования свойств только для чтения является «поздняя» инициализация, при которой мы не присваиваем свойству никакого значения до тех пор, пока оно не будет непосредственно запрошено клиентским кодом. Это является очень полезной возможностью при оптимизации приложения, которое выполняет большое количество запросов к базе данных.

  • Если мы опускаем процедуру Get свойства и используем ключевое слово WriteOnly при описании свойства, то свойство становится только для записи; оно может быть полезно, если класс имеет внутренний конфигурирующий флаг, который мы хотим выставлять, но никогда не хотим проверять. Однако, создание свойства, доступного для чтения, редко используется.

CLR в .NET Framework поддерживает два различных вида свойств:

Скалярные свойства. Скалярное свойство представляет одно значение. Значение может быть простым, таким как Integer или String, или сложным, таким как объект типа DateTime или Color.

Индексированные свойства. Индексированное свойство представляет коллекцию (набор) значений. Клиентский код использует синтаксис массива для доступа к конкретным значениям из этой коллекции.

Начнем рассмотрение скалярных свойств на примере свойства Name класса Person. Класс Person имеет поле с именем MName, которое содержит имя человека. Это поле объявлено как Private для запрещения доступа к нему непосредственно из клиентского кода. Как мы уже несколько раз повторяли, одной из наиболее важных целей объектно-ориентированной разработки является сохранение инкапсуляции класса. Другими словами: «Не объявляйте полей Public».



Public Class Person

Private MName As String

Public Property Name() As String

Get


Return MName

End Get


Set(ByVal Value As String)

MName = Value

End Set

End Property



End Class



Следующий фрагмент кода показывает, как использовать свойство Name, определенное в классе Person

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

Dim APerson As New Person

APerson.Name = TextBox1.Text

MsgBox(APerson.Name)

End Sub


Рассмотрим описание свойств для чтения/записи, только для чтения и только для записи. Свойство Name в предыдущем примере являлось свойством для чтения/записи. Определим свойство только для чтения на примере информации о дне рождения человека, а свойство только для записи на примере свойства EmailAlias для установки имени e-mail-адреса человека. Имя e-mail-адреса человека представляет первую часть e-mail-адреса сотрудника фирмы, стоящую перед именем домена. Это имя может быть изменено, но к нему никогда нельзя осуществить доступ (вместо этого, клиентская программа получает полный e-mail-адрес). Свойство EmailAddress для получения полного e-mail адреса. E-mail адрес формируется каждый раз при обращении к нему путем добавления имени домена компании к имени адреса человека.

Public Class Person

Private MName As String

Private MDob As DateTime

Private MEmailAlias As String

Public Sub New(ByVal name As String, ByVal Dob As DateTime)

MName = name

MDob = Dob

End Sub


Public Property Name() As String

Get


Return MName

End Get


Set(ByVal Value As String)

MName = Value

End Set

End Property



Public ReadOnly Property DOB() As DateTime

Get


Return MDob

End Get


End Property

Public WriteOnly Property EmailAlias() As String

Set(ByVal Value As String)

MEmailAlias = Value

End Set

End Property



Public ReadOnly Property EmailAddress() As String

Get


Return MEmailAlias & "@MyCompany.com"

End Get


End Property

End Class





Работа со свойствами только чтения или записи выглядит, например, следующим образом:

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

Dim APerson As New Person("Петров В.Н.", New DateTime(1978, 7, 2))

TextBox1.Text = APerson.Name

TextBox2.Text = APerson.DOB.ToLongDateString

APerson.EmailAlias = "Petrov"

TextBox3.Text = APerson.EmailAddress

End Sub


Разделяемое свойство (Shared-свойство) представляет собой часть информации, общей для всего класса, которую мы хотим представить как часть класса, а не как часть конкретного экземпляра класса. Клиентский код получает доступ к разделяемым свойствам через класс, а не через экземпляр этого класса. Следующий пример показывает, как определить разделяемое свойство Domain для представления имени домена, которое используется как часть e-mail-адреса человека.

В коде класса появится еще один фрагмент кода:



Public Class Person

Private Shared MDomain As String

Public Shared Property Domain() As String

Get

Return MDomain

End Get

Set(ByVal Value As String)

MDomain = Value

End Set

End Property

Public ReadOnly Property EmailAddress() As String

Get

Return MEmailAlias & "@" & MDomain

End Get

End Property



Воспользоваться этим разделяемым свойством можно, например, таким образом:




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

Dim APerson As New Person("Петров В.Н.", New DateTime(1978, 7, 2))

Person.Domain = "MyCoolSite.com"

APerson.EmailAlias = "Petrov"

TextBox1.Text = APerson.EmailAddress

End Sub


Обратите внимание на следующие моменты в этом примере:

  • Свойство Domain разделяемое.

  • Свойство EmailAddress использует имя домена для генерации полного E-mail-адреса человека.

  • Процедура Button1_Click устанавливает свойство Domain, используя имя класса Person, а не имя экземпляра класса APerson.

Выводы


Языки программирования, так же как и естественные языки общения, сильно влияют на способ мышления человека. Есть очень много интересных исследований лингвистов по этому поводу. Например, работа Р. Логана «Эффект алфавита» объясняет, почему наука и логика возникли на Западе, а развитая технология – в Китае.

Объектно-ориентированное программирование – это стиль мышления, а не технология. Если среда разработки не позволяет использовать ту или иную технологию, то программист бессилен что-нибудь изменить, но никто не может запретить ему мыслить объектами. ООП-стиль можно реализовать и на языке С, и на QuickBasic, и даже на языке Ассемблера. Проблема в том, что эти языки не стимулируют объектно-ориентированный стиль мышления. Объектно-ориентированные языки программирования непосредственно поддерживают основные принципы ООП, такие как создание объектов на основе классов, использование наследования, применение полиморфизма. При использовании других (не объектно-ориентированных) языков программирования приходится не только думать об архитектуре проекта, но и «сражаться» с языком, который не позволяет наследовать классы друг от друга или создавать сложные объекты. Итак, главная задача объектно-ориентированного языка – облегчить разработку проекта в рамках парадигмы ООП.


Вопросы для самопроверки


  1. Как вы считаете, не находятся ли в противоречии процессы инкапсуляции, как процесса сокрытия кода реализации свойств и методов класса, и полиморфизма, как процесса изменения, расширения кода свойств и методов классов наследников?

  2. Если при описании класса не было объявлено области его видимости, то какую область видимости такой класс будет иметь по умолчанию?

  3. Чем отличаются атрибуты класса от свойств класса?

  4. Для чего применяются свойства с ключевым словом ReadOnly?

  5. Для чего применяются свойства с ключевым словом WriteOnly?

  6. В чем отличие скалярных свойств класса от индексированных свойств класса?

  7. Для чего используются разделяемые Shared-свойства класса? В чем состоит особенность их использования?

Литература


  1. Ольсен Э., Эллисон д., Спир Дж. Visual Basic .NET. Разработка классов. Справочник/Практ. Пособ./Пер. с англ. — М. Издательство «СП ЭКОМ», 2006. – 416 с. ил.

  2. Троелсен Э. C# и платформа .NET. Библиотека программиста — СПб.: Питер, 2006 — 796 с.: ил.

  3. Объектно-ориентированное программирование в Visual Basic.NET. Библиотека программиста / Д. Кларк. – СПб.: Питер, 2005. – 352 с.: ил.

  4. Visual Basic.NET: учебный курс/ В.Долженков, М.Мозговой. — СПб.: Питер, 2005. – 465 с,: ил.


База данных защищена авторским правом ©bezogr.ru 2016
обратиться к администрации

    Главная страница