Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы по информатике.doc
Скачиваний:
61
Добавлен:
20.09.2019
Размер:
1.29 Mб
Скачать

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

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

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

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

  1. Инкапсуляция. Комбинирование записей с процедурами и функциями, манипулирующими полями этих записей, формирует новый тип данных - объект.

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

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

Парадигмы программирования

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

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

К директивным языкам относятся такие классические языки программирования, как Algol, Fortran, Basic, Pascal, C. Наиболее существенными классами декларативных языков являются функциональные (functional) или аппликативные, и логические (logic) языки. К категории функциональных языков относятся, например, Lisp и Haskell. Самым известным языком логического программирования является Prolog (Пролог). Среди объектно-ориентированных языков программирования (языков ООП) отметим C++, Java, Python и Ruby.

Отложим пока обсуждение концепции ООП и поговорим о различии между первыми двумя парадигмами. Главное заключается в следующем: декларативная программа заявляет (декларирует), что должно быть достигнуто в качестве цели, а директивная предписывает, как ее достичь.

Поясним это на следующем примере. Предположим, вам надо пройти в городе из пункта А в пункт Б. Декларативная программа - это план города, в котором указаны оба пункта, плюс правила уличного движения. Руководствуясь этими правилами и планом города, курьер сам найдет путь от пункта А к пункту Б.

Директивная программа - это список команд примерно такого рода: от пункта А по ул. Садовой на север до площади Славы, оттуда по ул. Пушкина два квартала, потом повернуть направо и идти до Театрального переулка, по этому переулку налево по правой стороне до дома 20, который и есть пункт Б.

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

Для классических директивных языков характерно, что последовательность выполняемых команд совершенно однозначно определяется ее входными данными. Как говорят, поведение исполнителя императивной программы полностью детерминировано.

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

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

Конструктор и деструктор

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

Конструктор - это подпрограмма, которая выполняется в момент создания объекта, а деструктор - удаления объекта. Для модуля это подпрограммы с именами BEGIN и END. При определении этих подпрограмм слово sub можно опускать.

Конструктор BEGIN выполняется сразу как только возможно, т.е. как только он определен, даже не завершая дальнейший разбор программы. Можно указать несколько блоков BEGIN. Они будут выполняться один за другим в порядке определения.

Деструктор END выполняется последним как только возможно, т.е. при завершении работы интерпретатора. Можно указать несколько блоков END, при этом они будут выполняться в обратном определению порядке.

Конструкторы и деструкторы

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

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

Данные динамической структуры:

К данным динамической структуры относят файлы, несвязанные и связанные динамические данные.

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

Статические и динамические переменные в Паскале

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

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

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

Предположим, например, что у вас есть программа, требующая массива в 400 строк по 100 символов каждая. Для этого массива требуется примерно 40К, что меньше максимума в 64К. Если остальные ваши переменные помещаются в оставшиеся 24К, массив такого объема проблемы не представляет. Но что если вам нужно два таких массива? Это потребовало бы 80К, и 64К сегмента данных не хватит. Другим общим примером является сортировка. Обычно когда вы сортируете большой объем данных, то делаете копию массива, сортируете копию, а затем записываете отсортированные данные обратно в исходный массив. Это сохраняет целостность ваших данных, но требует также наличия во время сортировки двух копий данных.

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

Динамическая память (ДП) – это оперативная память ПК, предоставляемая программе при ее работе, за вычетом сегмента данных (64 Кб), стека (16 Кб) и собственно тела программы. Размер динамической памяти можно варьировать. По умолчанию ДП – вся доступная память ПК.

ДП – это фактически единственная возможность обработки массивов данных большой размерности. Многие практические задачи трудно или невозможно решить без использования ДП. Например, при разработке САПР статическое распределение памяти невозможно, т.к. размерность математических моделей в разных проектах может значительно различаться.

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

Адресация динамических переменных осуществляется через указатели. Их значения определяют адрес объекта.

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

Выделение памяти под динамическую переменную;

Инициализация указателя;

Освобождение памяти после использования динамической переменной.

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

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