Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

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

.pdf
Скачиваний:
6
Добавлен:
05.02.2023
Размер:
4.5 Mб
Скачать

Министерство образования и науки Российской Федерации

ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)

Романенко В.В.

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ

Учебное пособие

Томск, 2014 г.

СОДЕРЖАНИЕ

 

1. Введение.....................................................................................................

6

2. Введение в технологию .NET ..................................................................

8

§ 2.1. Принципы объектно-ориентированного программирования .....

8

2.1.1. Понятие объекта и класса............................................................

8

2.1.2. Три основных принципа ООП ..................................................

13

§ 2.2. Технология Microsoft .NET...........................................................

22

2.2.1. Платформа Microsoft .NET........................................................

22

2.2.2. Common Language Runtime .......................................................

23

2.2.3. Библиотеки классов .NET Framework ......................................

24

2.2.4. Microsoft Intermediate Language и компиляторы JITter ..........

26

2.2.5. Унифицированная система типов ............................................

28

2.2.6. Преимущества .NET...................................................................

33

§ 2.3. Hello, World!...................................................................................

36

2.3.1. Выбор среды разработки ...........................................................

36

2.3.2. Создание программы .................................................................

39

2.3.3. Компиляция ................................................................................

46

2.3.4. Выполнение ................................................................................

49

2.3.5. Анализ исходного кода..............................................................

51

2.3.6. Анализ кода MSIL ......................................................................

54

2.3.7. Файлы с примерами ...................................................................

58

§ 2.4. Среда разработки ...........................................................................

60

2.4.1. Организация проекта .................................................................

60

2.4.2. Редактор кода..............................................................................

62

2.4.3. Встроенный отладчик ................................................................

65

3. Основы языка C#.....................................................................................

73

§ 3.1. Типы данных. Идентификаторы ..................................................

78

3.1.1. Базовый класс System.Object.....................................................

78

3.1.2. Типы данных по значению........................................................

81

3.1.3. Типы данных по ссылке ..........................................................

109

3.1.4. Анонимные типы......................................................................

123

3.1.5. Упаковка....................................................................................

125

3.1.6. Переменные и идентификаторы .............................................

126

§ 3.2. Форматирование. Консольный ввод и вывод ...........................

132

3.2.1. Методы Format и ToString .......................................................

132

2

 

3.2.2. Вывод на консоль.....................................................................

157

3.2.3. Методы Parse и TryParse..........................................................

159

3.2.4. Ввод с консоли .........................................................................

166

§ 3.3. Вычисление выражений..............................................................

170

3.3.1. Набор операторов языка C# ....................................................

170

3.3.2. Приоритет и порядок выполнения .........................................

171

3.3.3. Описание операторов...............................................................

173

3.3.4. Операции со строками .............................................................

186

3.3.5. Операции с перечислениями...................................................

187

3.3.6. Операции с типом DateTime ...................................................

188

3.3.7. Математические вычисления..................................................

189

§ 3.4. Операторы языка .........................................................................

193

3.4.1. Основные понятия....................................................................

193

3.4.2. Операторы ветвления ..............................................................

195

3.4.3. Операторы цикла......................................................................

201

3.4.4. Операторы перехода ................................................................

205

3.4.5. Работа с исключительными ситуациями ...............................

209

§ 3.5. Файловый ввод и вывод ..............................................................

219

3.5.1. Перечень основных классов файлового ввода-вывода ........

219

3.5.2. Потоковый ввод и вывод .........................................................

219

3.5.3. Управление ресурсами потока................................................

222

3.5.4. Сохранение и загрузка состояния приложения ....................

223

§ 3.6. Директивы препроцессора..........................................................

234

3.6.1. Директивы объявлений............................................................

234

3.6.2. Директивы условной компиляции..........................................

235

3.6.3. Директивы диагностики ..........................................................

237

3.6.4. Директивы регионов ................................................................

238

3.6.5. Директивы дополнительных опций .......................................

239

4. Классы и интерфейсы ...........................................................................

242

§ 4.1. Пространства имен ......................................................................

242

4.1.1. Описание пространства имен .................................................

243

4.1.2. Директивы использования ......................................................

245

4.1.3. Ссылки на сборки.....................................................................

248

§ 4.2. Описание класса ..........................................................................

254

4.2.1. Модификаторы класса .............................................................

254

3

 

4.2.2. Члены класса.............................................................................

257

4.2.3. Статические члены и члены экземпляров .............................

260

4.2.4. Создание и удаление экземпляров класса .............................

263

4.2.5. Вложенные типы ......................................................................

265

§ 4.3. Описание полей класса ...............................................................

266

4.3.1. Константы .................................................................................

266

4.3.2. Поля ...........................................................................................

266

§ 4.4. Описание методов класса ...........................................................

270

4.4.1. Синтаксис описания методов..................................................

270

4.4.2. Конструкторы ...........................................................................

276

4.4.3. Деструкторы .............................................................................

280

4.4.4. Метод Main ...............................................................................

280

§ 4.5. Свойства. Индексаторы...............................................................

282

4.5.1. Определение и использование свойств..................................

282

4.5.2. Индексаторы .............................................................................

288

§ 4.6. Наследование ...............................................................................

291

4.6.1. Свойства наследования............................................................

291

4.6.2. Доступ к членам при наследовании .......................................

293

4.6.3. Абстрактные классы ................................................................

296

4.6.4. Изолированные классы............................................................

297

§ 4.7. Перегрузка и полиморфизм ........................................................

299

4.7.1. Статический полиморфизм .....................................................

299

4.7.2. Виртуальный полиморфизм ....................................................

300

4.7.3. Перегрузка операторов ............................................................

305

§ 4.8. Делегаты и события.....................................................................

315

4.8.1. Предыстория вопроса ..............................................................

315

4.8.2. Методы обратного вызова.......................................................

319

4.8.3. Определение событий с помощью делегатов........................

324

§ 4.9. Интерфейсы..................................................................................

328

4.9.1. Объявление интерфейсов ........................................................

328

4.9.2. Реализация интерфейсов .........................................................

329

4.9.3. Интерфейсы и наследование...................................................

334

4.9.4. Примеры использования интерфейсов ..................................

337

5. Специальные возможности ..................................................................

347

§ 5.1. Универсальные типы...................................................................

347

4

 

5.1.1. Параметры типа........................................................................

347

5.1.2. Ограничения параметров типа................................................

355

5.1.3. Стандартные универсальные типы ........................................

359

§ 5.2. Потоки...........................................................................................

360

5.2.1. Основы организации потоков .................................................

360

5.2.2. Работа с потоками ....................................................................

363

5.2.3. Безопасность и синхронизация потоков ................................

378

§ 5.3. Метаданные и отражение ...........................................................

387

5.3.1. Иерархия API отражения.........................................................

387

5.3.2. Работа со сборками и модулями .............................................

391

5.3.3. Позднее связывание и отражение...........................................

394

5.3.4. Создание и исполнение кода в период выполнения.............

398

§ 5.4. Атрибуты ......................................................................................

401

5.4.1. Синтаксис описания атрибутов ..............................................

401

5.4.2. Определение и запрос атрибутов ...........................................

404

5.4.3. Атрибут AttributeUsage............................................................

408

5.4.4. Стандартные классы атрибутов..............................................

412

§ 5.5. Неуправляемый код.....................................................................

415

5.5.1. Службы Platform Invocation Services......................................

415

5.5.2. Написание небезопасного кода...............................................

420

§ 5.6. Комментарии и документирование кода...................................

428

5.6.1. Комментирование кода............................................................

428

5.6.2. XML-документирование кода C# ...........................................

430

6. Заключение ............................................................................................

441

Список литературы ...................................................................................

442

Приложения ...............................................................................................

443

Приложение А. Объекты для работы с датой и временем ................

443

Приложение Б. Объекты для работы со строками .............................

448

Приложение В. Объекты для работы с массивами ............................

455

Приложение Г. Объекты форматирования .........................................

459

Приложение Д. Объекты файлового ввода-вывода ...........................

466

5

1. ВВЕДЕНИЕ

Целью изучения курса «Объектно-ориентированное программирование» является получение студентами знаний о способах конструирования программ с применением языков C++ и C#.

Задачи курса:

изучить основные принципы объектно-ориентированного программирования на языке C++;

освоить технологию программирования в среде .NET;

изучить основы языка C# – типы данных, форматирование вводавывода, вычисление выражений, операторы ветвления и итераций, создание структур данных, классов, интерфейсов;

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

освоить среду разработки приложений .NET, отладку и документирование кода.

Желательно, чтобы, приступая к изучению данного курса, читатель уже владел языком программирования C, а также имел представление об основах программирования в ОС Windows (система сообщений, организация процессов и потоков, API).

В данном учебном пособии предлагаются несколько сред для разработки приложений на языках C++ и C#. К пособию прилагаются примеры, основная часть которых выполнена в среде Microsoft Visual Studio 2008, хотя для их компиляции можно использовать и другие среды. Если в тексте пособия встречается следующее обозначение:

Пример: Samples\2_1_1.

это означает, что примеры, рассмотренные в данном разделе, прилагаются к учебному пособию и располагаются в папке «Samples\2_1_1». В этой папке находится только один проект, его имя совпадает с именем папки, а расширение файла проекта – «.sln». Таким образом, в данном случае файл проекта будет иметь имя «2_1_1.sln». Стандартное имя главного файла с исходным кодом в проекте – «Program.cs». В большинстве проектов это единственный исходный файл. Все исключения из этих правил будут оговариваться отдельно.

6

Также при рассмотрении синтаксиса различных конструкций, будут использованы условные обозначения в виде квадратных и угловых скобок, а также многоточий. Фигурные скобки используются для группировки параметров. Квадратные скобки означают, что параметр, заключенный в них, является необязательным в данной синтаксической конструкции. Угловые скобки используются для условных обозначений. Т.е. текст, помещенный в них, следует использовать не буквально, а заменять его фактической конструкцией. Многоточие означает повторение предыдущей конструкции (от нуля и более раз). Вертикальная черта – альтернативный синтаксис. Например:

{[<имя диска>:][\<имя каталога> ...]\<имя файла>} | nul {[<имя диска>:][\<имя каталога>[\...]]\<имя файла>} | nul

Здесь формально задается спецификация файла. Имя диска и каталога является необязательным. При составлении фактической спецификации обозначение <имя диска> должно быть заменено фактическим именем диска (C, D и т.п.), и т.д. Каталоги могут быть вложенными, что и показано многоточием (приведены два эквивалентных варианта). Вместо имени файла можно указать виртуальный файл nul.

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

int"[]" <имя>; // Описание переменной

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

7

2. ВВЕДЕНИЕ В ТЕХНОЛОГИЮ .NET

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

(ООП).

§ 2.1. Принципы объектно-ориентированного программирования

Вэтом разделе мы познакомимся с терминологией ООП и убедимся в важности применения в программировании объектно-ориентированных концепций. Бытует мнение, что во многих языках, таких как C++ и Microsoft Visual Basic, есть «поддержка объектов», однако на самом деле лишь немногие из них следуют всем принципам, составляющим основу ООП, и язык C#

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

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

2.1.1.Понятие объекта и класса

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

8

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

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

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

Очевидно, что объектно-ориентированный подход естественнее и ближе к тому способу рассуждений, которым мы руководствуемся при решении задач. Во втором варианте объект «счет-фактура», наверно, просматривает в цикле совокупность (collection) объектов, представляющих данные по каждой позиции, посылая им запросы на получение суммы по данной позиции. Но если требуется получить только общий итог, то нам все равно, как это реализовано, так как одним из основных принципов объектноориентированного программирования является инкапсуляция (encapsulation). Инкапсуляция – это свойство объекта скрывать свои внутренние данные и методы, представляя наружу только интерфейс, через который осуществляется программный доступ к самым важным элементам объекта. Как объект выполняет задачу, не имеет значения, главное, чтобы он справлялся со своей работой. Имея в своем распоряжении интерфейс объекта, мы заставляем объект выполнять нужную нам работу.

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

9

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

Допустим, мы пишем приложение для расчета зарплаты служащим нашей компании. Код на C, представляющий данные о служащем, будет выглядеть примерно так:

struct EMPLOYEE

{

char szName[25]; int iAge;

double dPayRate;

};

А код для расчета зарплаты, например, Анны, в котором используется структура EMPLOYEE, выглядит так:

void main()

{

double dTotalPay; struct EMPLOYEE *pEmp;

pEmp = (EMPLOYEE *)malloc(sizeof(EMPLOYEE)); if (pEmp)

{

pEmp->dPayRate = 100; strcpy(pEmp->szName, "Анна"); pEmp->iAge = 28;

dTotalPay = pEmp->dPayRate * 40;

printf("Зарплата Анны составляет %g\n", dTotalPay);

}

free(pEmp);

}

Код этого примера основан на данных, содержащихся в структуре, и на некотором внешнем (по отношению к структуре) коде, обрабатывающем эту структуру. И что же здесь не так? Основной недостаток – в отсутствии абстрагирования: при работе со структурой EMPLOYEE необходимо знать чересчур много о данных, описывающих служащего. Почему это плохо? Допустим, спустя какое-то время нам потребуется определить «чистую» зарплату Анны (после удержания всех налогов). Тогда пришлось бы не только изменить всю клиентскую часть кода, работающую со структурой EMPLOYEE, но и составить описание (для других программистов, которым может достаться этот код впоследствии) изменений в функционировании программы.

10