Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

История и развитие методологии объектно-ориентированного программирования. Сферы применения (Языки процедурного программирования)

Содержание:

Введение

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

1. Понятие и классификация языков программирования

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

Структура команды ЭВМ в самой простейшей её вариации состоит из двух частей таких как[1]:

  1. Операционная часть – это код операции (сложение, вычитание и т.д.)
  2. Адресная часть – это адреса ячеек памяти; в них хранятся значения операндов, с которыми надо выполнить заданную операцию. По количеству указанных адресов в команде, различают одно-, двух-, трехадресные команды.

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

Данный способ программирования был сложен, неудобен. Язык программирования слишком громоздок при написании на нем кода можно легко допустить ошибку, достаточно было записать в неправильном порядке единицу или ноль. Программировать на таком языке очень сложно так как программу очень трудно контролировать. Еще одна сложность заключается в том, что для программирования на машинном языке необходимо знать внутреннюю структуру ЭВМ и принцип работы каждого блока[3]. Ну и самое плохое в таком методе программирования то, что программист затрачивает много времени, труда и повышенного внимания для написания программ на машинном языке.

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

Язык программирования – формализованный язык для описания алгоритма решения задачи на компьютере.

Для упрощения и автоматизации программирования на машинном коде каждой ЭВМ разрабатывался свой автокод (или Ассемблер), этот язык в полной мере повторяет набор команд машинного языка.

Дальнейшее развитие языковых средств шло по пути создания машинно-независимых языков, позволяющих писать программы на любой доступной ЭВМ с предусмотренной возможностью переноса на более совершенную архитектуру[5].

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

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

  • машинные языки (computer language) – языки программирования, воспринимаемые аппаратной частью компьютера (машинные коды);
  • машинно-ориентированные языки (computer oriented language) – языки программирования, которые отражают структуру конкретного типа компьютера (Ассемблеры);
  • алгоритмические языки (algorithmic language) – не зависящие от архитектуры компьютера языки программирования для отражения структуры алгоритма (Паскаль, Фортран, Бейсик и др.);
  • процедурно-ориентированные языки (procedure oriented language) – языки программирования, где имеется возможность описания программы как совокупности процедур (подпрограмм);
  • проблемно-ориентированные языки (universal programming language) – языки программирования, предназначенные для решения задач определенного класса (Лисп, РПГ, Симула и др.);
  • интегрированные системы программирования.

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

  • процедурные;
  • функциональные;
  • логические;
  • объектно-ориентированные.

Программа на процедурном языке программирования состоит из последовательности операторов (инструкций), задающих те или иные действия. Одним из важнейших квалификационных признаков процедурных языков является их уровень, характеризующий степень близости языка программирования и машинного языка. За начало отсчета уровней принимается машинный язык, уровень которого равен нулю. Язык человека рассматривается как язык наивысшего уровня[6].

2. История появления языков программирования

Еще в древности наши предки пытались создать устройства, облегчающие процесс вычисления к примеру древние греки и римляне применяли приспособление, подобное счетам, абак. Трое ученых в XV веке немецкие ученые В. Шиккард (1623) [7], Г.Лейбниц (1673) [8] и французский ученый Б. Паскаль (1642) [9] создали механические вычислительные устройства – предшественники всем известного арифмометра.

Принцип программного управления и запоминаемой программы были предсказаны Ч. Бэббиджем при работе над проектом аналитической машины «Машины для исчисления разностей»[10]. Ч. Бэббидж долгие годы плодотворно сотрудничал с Адой Лавлейс. Ада Лавлейс в 1843 году перевела статью Менабреа по лекциям Ч. Бэббиджа, где в виде подробных комментариев (по объему они превосходили основной текст) сформулировала главные принципы программирования аналитической машины[11]. Первая программа для машины Бэббиджа была разработана Адой Лавлейс, также она убедила учёного в том, что в изобретении необходимо использовать двоичную систему исчисления, именно она разработала принцип программирования и предложила термины «рабочая ячейка» и «цикл».

Именно Адой Лавлейс для решения системы двух уравнений и вычисления чисел Бернулли были составлены первые программы, а также она выдвинула предположение, что в будущем аналитическая машина сможет сочинять музыкальные произведения, рисовать картины и использоваться в практической и научной деятельности. Своими работами А. Лавлейс заложила теоретические основы программирования и по праву считается первым в мире программистом и основоположником научного программирования.

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

В 1950-х гг. программирование возникает как профессия и область науки. Первые программы составлялись вручную на машинных языках, они были громоздки, и отладка таких программа была – очень трудоемкой. Создание мнемокодов помогло упростить приемы и методы составления и отладки программ, мнемокоды используют символьную адресацию и являются близкими по своей структуре к машинному коду. Для перевода программы записанной в мнемокоде на машинный язык использовали Ассемблер[12]. Далее возникла необходимость в таком коде, который позволил бы обмениваться программами с возможностью применения на различных машинах, такое решение было найдено и названо автокод. Автокод - набор псевдокоманд для решения специализированных задач, например, научных или инженерных[13].

До конца 1950-х гг. основным элементом конструкции ЭВМ были электронные лампы (1-го поколения). В этот период развитие идеологии и техники программирования шло за счет достижений американских ученых Дж. фон Неймана[14], сформулировавшего основные принципы построения ЭВМ, и Дж. Бэкуса, под руководством которого в 1954 г. был создан Fortran (Formula Translation) - первый язык программирования высокого уровня, используемый до настоящего времени в разных модификациях. Так, в 1965 г. в Дартмутском колледже Д. Кэмэни и Т. Куртцем была разработана упрощенная версия Фортрана -Basic. В 1966 г. комиссия при Американской ассоциации стандартов (ASA) разработала два стандарта языка: Фортран и Базисный Фортран. Используются также дальнейшие модификации языка (например, 1970, 1990 гг.).

А.А. Ляпуновым[15] в 1953 году был предложен операторский метод программирования, сама идея заключалась в том, чтобы автоматизировать программирование, в таком методе алгоритм решения задачи представлялся в виде совокупности операторов, которые образовали логическую схему задачи. Схемы позволяли расчленить громоздкий процесс составления программы, части которой составлялись по формальным правилам, а затем объединялись в целое. В 1954 году в СССР создана первая программирующая программа ПП-1, данная программа была разработана именно для проверки идей операторного метода, её более совершенная версия ПП-2 была разработана в 1955 году. Разработки в данном направлении привели к созданию ПП БЭСМ в 1956 году, 1957 г. - ППСВ, в 1958 г. - для машины «Стрела».

В 1954 году в США стал применятся схожий по существу с оперативным методом алгебраический подход. В 1956 г. корпорацией IBM разработана универсальная ПП Фортран для автоматического программирования на ЭВМ IBM/704[16].

В этот период по мере накопления опыта и теоретического осмысления совершенствовались языки программирования. В 1958 -1960 гг. в Европе был создан ALGOL, который породил целую серию алголоподобных языков: Algol W, (1967), Algol 68, Pascal (Н. Вирт, 1970 г.), С (Д. Ритчи и Б. Керниган, 1972 г.), Ada (под руководством Ж. Ишбиа, 1979 г.), C++ (1983).

На начало 1970-х гг. существовало более 700 языков высокого уровня и около 300 трансляторов для автоматизации программирования.

2.1 Поколение языков программирования

Из большого числа языков программирования, возникших за период развития информационных технологий, общество разработчиков приняло только те языки, которые были наиболее удобными и совершенными[17].

Анализируя языки программирования и обстоятельства, сопутствующие их появлению, можно обнаружить множество общих черт. Это позволяет сгруппировать языки по основным используемым принципам и выделить поколения в их развитии. Буч приводит следующую классификацию Вегнера[18]:

  • Первое поколение (1954 – 1958 г.г.)

FORTRAN I Математические формулы

ALGOL-58 Математические формулы

Flowmatic Математические формулы

IPL V Математические формулы

  • Второе поколение (1959 – 1961 г.г.)

FORTRAN II Подпрограммы, раздельная компиляция

ALGOL 60 Блочные структуры, типы данных

COBOL Описание данных, работа с файлами

Lisp Обработка списков, указатели, сборка мусора

  • Третье поколение (1962 – 1970 г.г.)

PL/1 FORTRAN+ALGOL+COBOL

ALGOL-68 Более строгий преемник ALGOL-60

Pascal Более простой преемник ALGOL-60

Simula Классы, абстрактные данные.

Широкое распространение мини- и микро-ЭВМ способствовало развитию языков программирования, также большую роль в развитии языков программирования сыграл рост числа разработчиков программного обеспечения, и многообразие операционных систем и различных сфер применения информационных технологий[19].

2.1.1 Первое поколение языков программирования

До появления языков программирования первого поколения, специалисты управляли ЭВМ непосредственно на уровне двоичных кодов, в то время первые цифровые ЭВМ были громоздки и очень несовершенны также они обладали малым объемом памяти и несовершенной системой ввода-вывода. Языки первого поколения существенно облегчили процесс программирования приблизили программирование к предметной области и отдалили его от конкретной машины. Их словарь практически полностью был математическим[20]. Топология языков первого и начала второго поколения приведена в рисунке 1.1.

Рисунок 1.1

Топология языков первого и начала второго поколения

Источник: В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-108

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

2.1.2 Второе поколение языков программирования

Изначально подпрограммы служили лишь для облегчения процесса написания программ. Подпрограммы будучи минимальными единицами переиспользования, стали своего рода кирпичиками при создании первых библиотек. Со временем они стали играть фундаментальную роль в декомпозиции программных систем[21].

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

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

Рисунок 1.2

Топология языков программирования конца второго и начала третьего поколения

Источник: В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-108

2.1.3 Третье поколение языков программирования

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

Модуль-отдельно компилируемая часть программы, состоящая из наборов данных и подпрограмм[22].

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

Сначала языки программирования не обладали развитыми механизмами защиты данных от использования их процедурами другого. Задача по защите данных легла на коллектив разработчиков, что способствовало появлению огромного количества языков, которые имели те или иные сильные и слабые стороны. Одним из наиболее развитых представителей языков третьего поколения стал язык ALGOL-68. Хоть язык ALGOL-68 и был достаточно труден для первоначального освоения, однако данный язык был универсален, реализовывал все разработанные к тому времени механизмы в алгоритмических языках и позволял разрабатывать системы корпоративного масштаба для больших ЭВМ.

Такие простые потомки языка ALGOL-60 как Pascal и C приобрели большую популярность благодаря распространению малых ЭВМ.

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

Появившейся во второй половине 70-х годов язык C он широко использовался в академической и учебной среде и приобрел наибольшую популярность среди профессиональных программистов[23], C был разработан для написания операционной системы Unix и имел гибкий лаконичный синтаксис, простую алгоритмическую структуру (в нем отсутствуют вложенные процедуры), стал очень популярным языком как системного, так и прикладного программирования. Следующие характеристики делают язык C языком системного программирования:

  • Низкоуровневое управление памятью (преобразование типов, наличие указателей на данные и функции);
  • Препроцессор;
  • Поддержка макросов.

Эти возможности были ранее доступны на малых ЭВМ только на уровне языка ассемблер.

Рисунок 1.3

Топология языков конца третьего поколения

Источник: В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-108

3. Языки процедурного программирования

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

3.1 Фортран

В США фирмой IBM в начале 50-х гг. был создан один из первых процедурных языков программирования высокого уровня его назвали Фортран[24].

Фортран разрабатывался для решения научно-технических задач, язык работал с такими объектами как:

  • Целые числа;
  • Вещественные числа;
  • Числовые переменные.

Выражения в нем формируются с помощью четырех арифметических действий:

  • Возведение в степень;
  • Логические операции И, ИЛИ, НЕ;
  • Операций отношения и круглых скобок.

Основные операторы Фортрана:

  • Ввод;
  • Вывод;
  • Присваивание;
  • Условный и безусловный переход;
  • Цикл;
  • Вызов подпрограмм.

Пример кода, написанного на языке Фортран:

Hello, World!

Фиксированный формат (символами «␣» выделены пробелы в позициях строки с 1 по 6):

␣␣␣␣␣␣PRINT*, 'Hello, World!'

␣␣␣␣␣␣END

Свободный формат:

print *, "Hello, World!"

end

3.2 Кобол

В период с 1958-1960 гг. в США был разработан язык программирования, ориентированный на решение задач обработки данных под названием COBOL (COmmon Business Oriented Language)[25]. Кобол предназначен, в первую очередь, для разработки бизнес-приложений по этой причине широко использовался для решения учетно-экономических и управленческих задач. Практически с самого своего рождения Кобол является ANSI-стандартизованным языком программирования. Программа на Коболе имеет вид ряда предложений на английском языке и напоминает обычный текст. Группы последовательно записанных операторов объединяются в предложения, предложения — в параграфы, параграфы — в секции. Программист присваивает параграфам и секциям имена (метки), что облегчает непосредственное обращение к нужному участку программы. В СССР был принят русский вариант языка. В Коболе были реализованы мощные средства работы с большими объемами данных, хранящимися на различных внешних носителях.

Пример кода, написанного на языке Кобол:

Hello world

IDENTIFICATION DIVISION.

PROGRAM-ID. HELLO-WORLD.

*

ENVIRONMENT DIVISION.

*

DATA DIVISION.

*

PROCEDURE DIVISION.

PARA-1.

DISPLAY "Hello, world.".

*

EXIT PROGRAM.

END PROGRAM HELLO-WORLD.

3.3. Алгол

В 1958 году на недельной конференции в ETH (Цюрих, Швейцария) как универсальный язык программирования для широкого круга применений, а затем доработан комитетом, созданным Международной федерацией по обработке информации (IFIP)[26]. Алгол предназначался для записи алгоритмов, построенных в виде последовательности процедур, применяемых при решении поставленных задач. В том же году была принята первая версия описания языка Алгол 58 (первоначально предполагалось назвать язык IAL — International Algebraic Language, но от этого отказались), для устранения проблем предыдущей версии комитет сформировал новый стандарт – Алгол 60; он и стал классическим Алголом. Годом позже в 1959 г. был разработан – формальный способ описания алгоритмических языков, названный в честь его создателя «нормальной формой Бэкуса» (БНФ). Первым языком, спецификация которого была записана в БНФ, стал Алгол 58. Впоследствии, после усовершенствований, которые предложил Питер Наур, возникла форма Бэкуса — Наура (аббревиатура та же — БНФ или BNF), которая использовалась для спецификации языка ALGOL 60 уже на этапе её разработки.

В Алголе в первые были введены такие понятия как: «блочная структура программы», «динамическое распределение программы». Внутри блока в Алголе можно вводить локальные обозначения, которые не зависят от остальной части программы. Несмотря на свое интернациональное происхождение, Алгол-60 получил меньшее распространение, чем Фортран. Например, не на всех зарубежных ЭВМ имелись трансляторы с Алгола-60. В 1968 г. в результате дальнейшего развития и усовершенствования Алгола-60 была создана версия Алгол-68[27]. Это многоцелевой универсальный расширенный язык программирования.

Пример кода, написанного на языке Алгол 60

procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);

value n, m; array a; integer n, m, i, k; real y;

comment Наибольший элемент матрицы a, размера n на m

передаётся в виде результата в y, а его индексы — в параметры i и k;

begin integer p, q;

y := 0; i := k := 1;

for p:=1 step 1 until n do

for q:=1 step 1 until m do

if abs(a[p, q]) > y then

begin y := abs(a[p, q]);

i := p; k := q

end

end Absmax

3.4. Бейсик

Из-за повышения доступности компьютеров в 1960-х годах и появления возможности работы в режиме разделения времени появилась потребность в простом для освоения языке программирования с наличием достаточно мощных универсальных средств, пригодных для решения научных, технических и экономических задач, а также задач бытового характера, игровых и т.д. Новый язык назвали универсальным символическим кодом для начинающих или сокращенно BASIC (Бейсик). 1964 г. считают годом рождения этого языка[28]. Бейсика его предназначался для более «простых» пользователей, не столько заинтересованных в скорости исполнения программ, сколько просто в возможности использовать компьютер для решения своих задач, не имея специальной подготовки. Согласно концепциям, заложенным в Бейсике, в нем широко распространены различные правила умолчания, что считается плохим тоном в большинстве языков программирования подобного типа. Возникло множество версий языка, зачастую мало совместимых друг с другом. Однако, зная одну из версий, можно без особого труда освоить любую другую. Бейсик активно поглощает многие концепции и новинки из других языков.

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

При проектировании языка использовались следующие восемь принципов.

Новый язык должен был:

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

Фрагмент программы на Бейсике:

10 CLS 'Очистка экрана

20 PRINT "Добро пожаловать!" 'Заголовок в первой строке

30 'Цикл, выводящий линию под заголовком, на всю ширину экрана

40 FOR I=1 TO 80

50 PRINT "=";

60 NEXT I

65 'Ввод символьных данных от пользователя (комментарий добавлен после ввода нижних строк)

70 INPUT "Имя: ",N$

80 INPUT "Фамилия: ",S$

90 INPUT "Отчество: ",T$

95 'Вырезаем копию первых символов из имени и отчества

100 N2$=LEFT$(N$,1)

110 T2$=LEFT$(T$,1)

120 'Выводим результат

130 PRINT "Ваше имя кратко: ";S$;" ";N2$;". ";T2$;"."

140 INPUT "Повторить программу? (Y/N) ",U$

150 IF U$="Y" THEN GOTO 10

160 END

3.5. ПЛ/1

В начале 1960-х гг. разрабатываемые программы для научной и бухгалтерской сфер использовали разные компьютеры и писались на разных языках: научные — на Фортране, бухгалтерские — в основном на Коболе, в связи с этим появилась необходимость в создании такого языка, который подходил для обоих типов приложений и поддерживал конструкции для структурного программирования, взятых из Алгола-60, не поддерживаемых в то время ни Коболом, ни Фортраном. Были предприняты попытки преодолеть этот недостаток путем создания универсального языка программирования. ПЛ /1 (PL /1 — Programming language One) — первый многоцелевой универсальный язык, разработан в США фирмой IBM в 1963—1966 гг[29].

ПЛ /1 один из наиболее распространенных универсальных языков, он хорошо приспособлен для решения задач в области вычислительной техники: исследования и планирования вычислительных процессов, моделирования, решения логических задач и исследования логических схем, разработки систем математического обеспечения.

Основные свойства языка ПЛ/1:

  • Свободный синтаксис;
  • Ключевые слова и идентификаторы нечувствительны к регистру;
  • По умолчанию (в классических версиях для мейнфреймов — всегда) передача параметров по ссылке;
  • Поддержка сложных структур с объединениями (в терминологии языка Паскаль — записи с вариантами);
  • Чрезвычайно развитая система встроенных типов данных, при этом возможность неявных преобразований между большинством из них;
  • Несколько видов динамического выделения памяти;
  • Очень обобщённые операторы со многими вариантами синтаксиса;
  • Строго определённая семантика управляющих конструкций (например, оператор цикла определён через эквивалентные присваивания и go to и т. д.);
  • Операции с массивами;
  • Развитый механизм исключительных состояний;
  • Поддержка на уровне языка мультизадачности и асинхронного ввода-вывода;
  • Поддержка на уровне языка сложных методов доступа для ввода-вывода;
  • Очень развитый препроцессор, фактически сам являющийся подмножеством ПЛ/1.

Первоначальный алфавит языка ПЛ/1 включал в себя 60 символов: $ @ # A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 = + — * / () , . ' % ; : ¬ & | > < _ ? и пробел, также Была предусмотрена возможность работы и с более ограниченным 48-символьным алфавитом, в который не входили символы @ # ; : ¬ & | > < _ ? — вместо отсутствующих символов использовались дополнительные ключевые слова:

60 символов

:

;

||

>

>=

<

<=

¬<

¬>

¬=

¬

|

&

->

48 символов

..

,.

CAT

GT

GE

LT

LE

NL

NG

NE

NOT

OR

AND

PT

Источник: http://www.osdata.com/topic/language/pli.htm

При разработке PL/1 были широко использованы основные понятия и средства языков Фортран, Алгол-60, Кобол. PL/1 — богатый и гибкий язык, дает возможность производить вставки, исправлять текст программы в процессе ее отладки. Язык получил широкое распространение, трансляторы с него имеются для многих типов компьютеров.

У ПЛ/1 были как достоинства, описанные выше, так и недостатки, поначалу ПЛ/1 вызвал большой энтузиазм, но оказался не так успешен, как планировалось, по следующим причинам:

  • Чрезвычайная сложность языка, в значительной мере потому, что язык был разработан комитетом, пытавшимся найти соглашение и удовлетворить нужды совершенно разных пользователей (научных и банковских).
  • Трудность реализации компилятора, и, как следствие, большое количество сбоев и ошибок и низкое качество первых компиляторов. Это возникало также из-за того, что ПЛ/1 содержал много почти не используемых большинством пользователей возможностей, вроде поддержки многозадачности.
  • Не оптимальность скомпилированного кода, что было очень критично для математических расчётов. Поэтому ПЛ/1 не смог заменить собой Фортран. Асинхронная модификация переменных (например, в результате конструкции on error) крайне затрудняла оптимизацию.
  • Компиляторы языка ПЛ/1 реализовывали различные подмножества языка, что приводило к непереносимости программ.

Хотя ПЛ/1 и не смог вытеснить Фортран и КОБОЛ (или даже сравниться с ними по популярности), тем не менее, он широко использовался во второй половине 1960-х и в 1970-х годах, особенно для бухгалтерских приложений, в основном из-за отсутствия в то время лучшей альтернативы[30]. Как Фортран, так и КОБОЛ были бедны по своим возможностям даже для задач того времени. ПЛ/1, напротив, представлял богатый набор средств.

Пример кода, написанного на языке ПЛ/1

Test: procedure options(main);

declare My String char (20) varying initialize ('Hello, world!');

put skip list (My String);

end Test;

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

Test: proc options (main);

put list ('Hello, world!');

end;

3.6. Паскаль

В 1968-1969 гг. Никлаусом Виртом в Высшей технической школе (ЕТН) в Цюрихе (Швейцария), создан как учебный процедурный язык программирования Паскаль (Pascal), он был назван в честь французского математика и философа Блеза Паскаля (1623—1662)[31].

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

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

  • Структурное программирование. Его методология основана на использовании подпрограмм и независимых структур данных, объединяющих связанные между собой совокупности данных. Подпрограммы позволяют заменять в тексте программ упорядоченные блоки команд, отчего программный код становится более компактным. Структурный подход обеспечивает создание более понятных и легко читаемых программ, упрощает их тестирование и отладку[33].
  • Программирование сверху вниз, когда задача делится на простые, самостоятельно решаемые подзадачи. Затем на основе решенных подзадач выстраивается решение исходной задачи полностью — сверху вниз[34].

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

Фирма Apple в 1986 году разработала объектное расширение языка Паскаль, получив в результате Object Pascal.

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

Пример программы на языке Паскаль, выводящей строку «Hello, world!»:

begin

writeln('Hello, World!'); { оператор вывода строки }

end.

3.7. Ада

Министерство обороны США решило навести порядок среди бесчисленного множества трансляторов и создало комитет для разработки одного универсального языка. Целью было получение языка программирования, который мог бы стать единым для разработки проектов по заказам военного ведомства, главным образом, для разработки встроенных систем военного назначения и для больших военных компьютеров (на базе процессора iAPX 432 от Intel). В 1975 году формируется набор требований к языку, который бы в полной мере удовлетворил разработчиков систем указанного типа[35].

Согласно сформированного набора требований был проведен анализ в ходе которого выяснилось, что ни один из имеющихся языков программирования не удовлетворяет требованиям в достаточной мере и на основании анализа принимается решение разработать новый язык программирования. В 1977 году объявляется конкурс на создания нового языка программирования, для разработки данного языка разработчикам предложили базироваться на одном из трёх языков: Паскаль, Алгол 68 или ПЛ/1[36].

В ходе проведения конкурса из 15 проектов было выбрано 4 (все основаны на Паскале), после доработки этих проектов были отобраны 2 проекта, из которых после очередной доработки, в мае 1979 года был объявлен победитель - группа ученых во главе с Жаном Ишбиа. Победивший язык назвали АДА, в честь Ады Лавлейс, дочери великого поэта Байрона. В 1983 году язык был официально стандартизован ANSI. Стандарт языка ANSI/MIL-STD-1815-A-1983 был утверждён 17 февраля 1983 года. Министерством обороны США регистрируется торговая марка под наименованием «Ada» и запрещает выпускать трансляторы языка, не прошедшие официальную процедуру тестирования на соответствие стандартам.

Язык АДА — прямой наследник Паскаля. Он предназначен для создания и длительного сопровождения больших программных систем, управления процессами в реальном масштабе времени. В языке четко выражена модульность его конструкций, причем обеспечивается удобство организации разнообразных связей между модулями. Важным его достоинством является возможность параллельного программирования ветвей программы, которые затем могут реализоваться на многопроцессорных компьютерах.

В 1987 году язык Ада был официально стандартизован ISO. С этого момента Министерство обороны США перевело язык в общественное достояние.

К 1990 году в мире существовало уже около 200 компиляторов, соответствовавших стандарту языка Ада.

В 1995 году был принят новый стандарт Ады, известный как Ada95[37]. В язык были введены средства объектного программирования. Кроме того, язык был дополнен более развитыми средствами для взаимодействия с программами, написанными на других языках.

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

В 2012 году ISO принят и опубликован новый стандарт языка.

Пример программы «Hello, world!» написанной на языке Ада:

with Ada.Text_IO;

procedure Hello is

use Ada.Text_IO;

begin

Put_Line("Hello, world!");

end Hello;

3.8. Си

В период с 1969 по 1973 годы в лабораториях Bell Labs компьютерным специалистом Деннисом Ритчи разработан компилируемый статически типизированный язык программирования общего назначения под названием Си[38]. Первоначально язык Си разрабатывался для реализации операционной системы UNIX и замены Ассемблера, чтобы иметь возможность создавать столь же эффективные и компактные программы, и в то же время не зависеть от конкретного типа процессора. В 1973 году большая часть ядра UNIX, первоначально написанная на ассемблере PDP-11/20, была переписана на Си. Это было одно из самых первых ядер операционных систем, написанное на языке, отличном от ассемблера.

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

По набору управляющих конструкций и структур данных С имеет возможности, присущие высокоуровневым языкам, и вместе с тем он располагает средствами прямого обращения к функциональным узлам компьютера. Синтаксис языка С позволяет создавать лаконичный программный код. Одна из существенных особенностей С, приближающая его к функциональным языкам, состоит в том, что различия между выражениями и операторами сглаживаются[39]. Например, выражения, являющиеся операторами программы, могут выполнять дополнительно операции присваивания. Использование подпрограмм основано на понятии функции, которая может также сочетать в себе возможности процедуры. Понятие процедуры в языке С отсутствует. Синтаксис языка затрудняет читаемость программы. Отсутствие строгой типизации данных, возможность в одном выражении сочетать несколько действий делает этот язык привлекательным для программистов, предоставляя им дополнительные возможности, но не способствует надежности создаваемых программ. Си имеет следующие основные особенности:

  • простую языковую базу, из которой вынесены в библиотеки многие существенные возможности, вроде математических функций или функций управления файлами;
  • ориентацию на процедурное программирование, обеспечивающую удобство применения структурного стиля программирования;
  • систему типов, предохраняющую от бессмысленных операций;
  • использование препроцессора для, например, определения макросов и включения файлов с исходным кодом;
  • непосредственный доступ к памяти компьютера через использование указателей;
  • минимальное число ключевых слов;
  • передачу параметров в функцию по значению, а не по ссылке (при этом передача по ссылке эмулируется с помощью указателей);
  • указатели на функции и статические переменные;
  • области действия имён;
  • структуры и объединения — определяемые пользователем собирательные типы данных, которыми можно манипулировать как одним целым.

В то же время в Си отсутствуют[40]:

  • вложенные функции;
  • сопрограммы;
  • средства автоматического управления памятью;
  • средства объектно-ориентированного программирования;
  • средства функционального программирования.

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

Язык программирования Си оказал существенное влияние на развитие индустрии программного обеспечения, а его синтаксис стал основой для таких языков программирования, как C++, C#, Java и Objective-C.

В настоящие время язык Си реализован для большинства компьютерных платформ.

Программа Hello, world! приведена ещё в первом издании книги «Язык программирования Си» Кернигана и Ритчи:

#include <stdio.h>

int

main(void) // Не принимает аргументы.

{

printf("Hello, world!\n"); // "\n" - новая строка.

return 0; // Удачное завершение программы.

}

4. Недостатки структурного программирования

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

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

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

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

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

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

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

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

5. Объектно-ориентированный подход к программированию

Объектно-ориентированное программирование- методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых являлся экземпляром определенного класса, а классы образуют иерархию наследования[42].

Разработчиками первого объектно-ориентированного языка в 1960г.Simula67 стали норвежские ученые Кристофер Нюгор и Оле-Йохан Даль. Они ввели такие понятия, как класс, объект, наследование, динамическое создание объектов и т.д. Сейчас эти термины являются неотъемлемыми основами всех современных ООЯ программирования- в частности языков Java и С++. Позднее американский ученый в области теорий вычислительных систем Алан Кертис Кэй разработает объектно-ориентированный язык Smalltalk основанный на языке Simula. Но Smalltalk разрабатывался как полностью динамичная система, в которой классы могут создаваться и изменяться динамически, а не только статически как в Simula. В доминирующую методологию объектно-ориентированное программирование сформировалось в начале и середине 1990-х годов, когда стали широко доступны поддерживающие ее языки программирования, такие как С++, Delphu и Visual FoxPro3.0

Основополагающей идеей объектно-ориентированного подхода является объединение данных и действий, производимых над этими данными, в единое целое, которое называется объектом[43].

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

6.1 Функции объекта

Функции объекта, именуемые в ООП как методы, предназначены для доступа к данным объекта. Для того, чтобы считать данные объекта и возвратить требуемое значение необходимо вызвать соответствующий метод. Доступ данных извне невозможен. Данные защищены от случайного изменения. Объединение данных и методов в одной сущности называется инкапсуляцией (ограничение доступа к определенным данным и/или методам называется скрытием данных)[44]. Если возникает необходимость изменить данные объекта, то действие это будет возложено на методы этого объекта. Никакие другие функции не способны изменить данные класса. Такая тактика делает написание программы более простым и удобным ее использование, а также отладку.

6.2 Объекты

Такое понятие, как объект в ООП является базовым. Объект-это некоторая сущность в компьютерном пространстве, обладающая определенным состоянием и поведением, имеющая заданные значения свойств (атрибутов) и операций над ними (методов). «Объект обладает состоянием, поведением и идентичностью; структура и поведение схожих объектов определяет общий для них класс; термины "экземпляр класса" и "объект" взаимозаменяемы»[45].

6.3 Атрибуты объектов

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

Различают два вида атрибутов: постоянные атрибуты (константы) и переменные атрибуты. Постоянные атрибуты характеризуют объект в его классе (напр. марка автомобиля). Переменные атрибуты характеризуют текущее состояние объекта (напр. скорость автомобиля во время его движения). Изменяя значения этих атрибутов, мы изменяем состояние объекта.

6.4 Классы

«Класс - это некое множество объектов, имеющих общую структуру и общее поведение»[46]. Когда мы говорим об объектах, мы говорим, что они являются экземплярами классов. Класс является своего рода формой определяющей какие данные(атрибуты) и функции будут включены в объект класса[47]. (Роберт Лафоре)

6.5 Методы класса

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

Приведем пример объекта на языке С++, моделирующий реально существующий объект. Создадим класс, назовем его класс Car, основой для которого послужит структура, описывающая свойства автомобиля. Класс Car состоит из 4-х полей: string brand, string color, power, maxSpeed. Метод класса Print () будет выводить на экран содержимое полей. Затем в функции main создадим экземпляр класса, назовем его SportsCar и присвоим переменным значения. Вызовем метод Print (), для объекта SportsCar. Метод Print () выведет информацию о полях класса в консоль.

#include <iostream>

#include <string>

using namespace std;

class Car //определение класса

{

public:

string brand; //поле класса

string color; //поле класса

int power; //поле класса

int maxSpeed; //поле класса

void Print() //функция или метод класса

{

cout << "\t Mарка" << brand << "\t Цвет" << color << "\t Мощность" << power << "\t Максимальная скорость" << maxSpeed << endl;

}

};

int main()

{

setlocale(LC_ALL, "ru");

Car SportsCar; //объект класса Car

SportsCar.brand = "Ferrari";

SportsCar.color = "red";

SportsCar.power = 660;

SportsCar.maxSpeed = 350;

SportsCar.Print(); //вызов метода Print() через объект класса SportsCar

return 0;

}

Программа выдаст следующий результат:
МаркаFerrari Цветred Мощность660 Максимальная скорость350

7. Основные принципы объектно-ориентированного программирования

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

«Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя»[48].

В Объектно-Ориентированном программировании абстракция- работа только со значимыми характеристиками. Суть принципа в том, чтобы отделить составные объекты, состоящие из «меньших» объектов, от составляющих этих самых объектов. «Все абстракции обладают как статическими, так и динамическими свойствами. Например, файл как объект требует определенного объема памяти на конкретном устройстве, имеет имя и содержание. Эти атрибуты являются статическими свойствами. Конкретные же значения каждого из перечисленных свойств динамичны и изменяются в процессе использования объекта: файл можно увеличить или уменьшить, изменить его имя и содержимое»[49].

7.1 Модификаторы доступа private и public

Модификаторы доступа служат для определения полномочий доступа к членам класса извне. Если перед полем или методом стоит ключевое слово private, то обращаться к данному члену можно только внутри класса. Член с модификатором public доступен за пределами класса т.е. другие классы могут напрямую получить или модифицировать значение поля (категорически не рекомендуется поле делать public, для безопасного получения и установки значения нужно использовать геттеры и сеттеры), либо вызвать публичный метод. Если метод или поле имеет модификатор доступа protected, то они прежде всего доступны самому классу и его наследникам.

С помощью модификаторов доступа реализуется ключевой принцип ООП-инкапсуляция данных (их скрытие). Если не указывать модификатор доступа, то по умолчанию он принимается равным: в С++, С# private, в Java public.

7.2 Инкапсуляция и скрытие данных

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

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

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

7.3 Интерфейсы

Интерфейс определяет основные средства коммуникации между объектами. При проектировании любого класса предусматриваются интерфейсы для надлежащего создания экземпляров и эксплуатации объектов. Любое поведение, которое обеспечивается объектом, должно вызываться через сообщение, отправляемое с использованием одного из предоставленных интерфейсов. В случае с интерфейсом должно предусматриваться полное описание того, как пользователи соответствующего класса будут взаимодействовать с этим классом. В большинстве объектно-ориентированных языков программирования методы, являющиеся частью интерфейсов, определяются как public[51].

Для того, чтобы скрыть данные, все атрибуты нужно объявить, как private. Атрибуты никогда не являются частью интерфейсов. Частью интерфейсов классов могут быть только открытые методы. Объявление атрибута как public нарушает концепцию скрытия данных. Если пользователю потребуется доступ к атрибуту, то для возврата значения этого атрибута будет сгенерирован специальный метод чтения, геттер, который позволяет получить данные, доступ к которым напрямую ограничен.

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

7.4 Наследование

Наследование - это такое отношение между классами, когда один класс повторяет структуру и поведение другого класса (одиночное наследование) или других (множественное наследование) классов. Класс, структура и поведение которого наследуются, называется суперклассом. Производный от суперкласса класс называется подклассом. Это означает, что наследование устанавливает между классами иерархию общего и частного. Таким образом подкласс является более специализированным классом, а суперкласс более общим. В подклассе структура и поведение исходного суперкласса дополняются и переопределяются. Подкласс обычно расширяет или ограничивает существующую структуру и поведение своего суперкласса[52].

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

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

7.4.1 Суперклассы и подклассы

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

Подкласс, или дочерний класс (иногда называемый производным), представляет собой расширение суперкласса. Таким образом, подклассы наследуют все общие атрибуты и поведения от суперкласса.

Наследование обеспечивает большое количество преимуществ в

плане проектирования. При проектировании производного класса базовый класс предоставляет значительную часть требуемой функциональности[54].

7.4.2 Множественное наследование

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

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

Проблема повторного наследования решается тремя способами. Во-первых, можно его запретить, отслеживая при компиляции. Так сделано в языках Smalltalk и Eiffel (но в Eiffel, опять-таки допускается переименование для устранения неопределенности). Во-вторых, можно явно развести две копии унаследованного элемента, добавляя к именам префиксы в виде имени класса-источника (это один из подходов, принятых в C++). В-третьих, можно рассматривать множественные ссылки на один и тот же класс, как обозначающие один и тот же класс. Так поступают в C++, где повторяющийся суперкласс определяется как виртуальный базовый класс. Виртуальный базовый класс появляется, когда какой-либо подкласс именует другой класс своим суперклассом и отмечает этот суперкласс как виртуальный, чтобы показать, что это - общий (shared) класс[55].

7.4.3 Спецификатор доступа protected

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

Предположим, что есть некий объект objA класса A. Метод funcA() является методом класса A. Оператор функции main() (или любой другой функции, не являющейся методом класса A) objA.funcA(); будет ошибочным, пока мы не объявим funcA() как public. Для объекта objA мы не можем использовать члены класса A, объявленные как private. Их могут использовать только методы самого класса A.

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

Таким образом, если вы пишете класс, который впоследствии будет использоваться как базовый класс при наследовании, то данные, к которым нужно будет иметь доступ, следует объявлять, как protected[56].

7.4.4 Недостатки использования спецификатора protected

Следует знать, что существуют и недостатки использования спецификатора доступа protected. Допустим, вы написали библиотеку классов и публично ее распространяете. Любой программист сможет получить доступ к членам классов, объявленным как protected, просто создавая производные классы. Это делает члены, объявленные как protected, значительно менее защищенными, чем объявленные как private. Чтобы избежать порчи данных, часто приходится разрешать доступ производным классам только к тем методам базового класса, которые объявлены как public. И все же использование спецификатора доступа protected значительно упрощает программирование[57].

8. Полиморфизм

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

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

Несмотря на то что полиморфизм тесно связан с наследованием, он часто упоминается отдельно от него как одно из наиболее весомых преимуществ объектно-ориентированных технологий. Если потребуется отправить сообщение объекту, он должен располагать методом, определенным для ответа на это сообщение. В иерархии наследования все подклассы наследуют от своих суперклассов. Однако, поскольку каждый подкласс представляет собой отдельную сущность, каждому из них может потребоваться дать отдельный ответ на одно и то же сообщение[58]. Полиморфизм обеспечивается за счет использования производных классов и виртуальных функций. Виртуальная функция — это функция, объявленная с ключевым словом virtual в базовом классе и переопределенная в одном или в нескольких производных классах. Виртуальные функции являются особыми функциями, потому что при вызове объекта производ­ного класса с помощью указателя или ссылки на него С++, например, основываясь на типе объекта во время исполнения про­граммы определяет, какую функцию вызвать.

Для разных объектов вызываются разные версии одной и той же виртуальной функции. Класс, содержащий одну или более вир­туальных функций, называется полиморфным классом (polymorphic class). Виртуальная функция объявляется в базовом классе с использованием ключевого слова virtual. Когда же она переопределяется в производном классе, повторять ключевое слово virtual нет не­обходимости, хотя и в случае его повторного использования ошибки не возникнет.

В качестве примера полиморфизма и виртуальной функции рассмотрим следующую короткую программу:

#include <iostream>

#include <string>

using namespace std;

class Base {

public:

virtual void who() { // определение виртуальной функции

}

};

class first_d : public Base {

public:

void who() { // определение who() применительно к first_d

cout << "First derivation\n";

}

};

class seconded : public Base {

public:

void who() { // определение who() применительно к second_d

cout << "Second derivation\n";

}

};

int main()

{

Base *p;

first_d first_obj;

seconded second_obj;

p = &first_obj;

p->who(); // доступ к who класса first_d

p = &second_obj;

p->who(); // доступ к who класса second_

return 0;

}

Программа выдаст следующий результат:

First derivation

Second derivation

Проанализируем подробно эту программу, чтобы понять, как она работает. Как можно видеть, в объекте Base функция who() объявлена как виртуальная. Это означает, что эта функция может быть переопределена в производных классах. В каждом из классов first_d и second_d функция who() переопределена. В функции main() объявлен указатель р на класс Base. Затем объявлены две переменные. Первой является объект first_obj, имеющий тип first_d и second_obj, относящийся к производному классу seconded . После этого объявлен указатель р на объекты first_obj и second_obj, относящиеся к двум производным классам. Далее указателю р при­своен адрес объекта first_obj и вызвана функция who(). Поскольку эта функция объявлена как виртуальная, то С++ определяет на этапе исполнения, какую из версий функции who() употребить, в зависимости от того, на какой объект указывает указатель р. В данном случае им является объект типа first_obj, поэтому исполняется версия функции who(), объявленная в классе first_obj. Затем указате­лю р присвоен адрес объекта second_obj. После того, как функция who() была вызвана, С++ снова анализирует тип объекта, на который указывает р, для того, чтобы определить версию фун­кции who(), которую необходимо вызвать. Поскольку р указывает на объект типа second_obj, то ис­пользуется соответствующая версия функции who().

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

Заключение

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

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

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

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

Библиография

  1. Гедранович, В.В. Основы компьютерных информационных технологий: учеб. -метод. комплекс / В.В. Гедранович, Б.А. Гедранович, И.Н. Тонкович.–2-е изд., стереотип.–Минск: Изд-во МИУ, 2011.– 344 с.
  2. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –232с.
  3. Г.Буч Объектно ориентированный анализ и проектирование с примерами приложений на С++, 2-е изд./Пер.с англ.—СПб.;М.: «Невский Диалект» — «Издательство БИНОМ», 1999г.
  4. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-108.
  5. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. – 902с.
  6. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — 304с.
  7. Основы информатики и вычислительной техники // URL: http://www.opengl.org.ru/osnovy-informatiki-i-vychislitelnoi-tekhniki/osnovy-informatiki-i-vychislitelnoi-tekhniki-str41.html (Дата обращения: 07.06.2018).
  8. Процедурное программирование // URL:https://mydocx.ru/10-47202.html (Дата обращения: 20.06.2018).
  1. Основы информатики и вычислительной техники//URL: http://www.opengl.org.ru/osnovy-informatiki-i-vychislitelnoi-tekhniki/osnovy-informatiki-i-vychislitelnoi-tekhniki-str41.html (Дата обращения: 07.06.2018)

  2. Гедранович, В.В. Основы компьютерных информационных технологий: учеб. -метод. комплекс / В.В. Гедранович, Б.А. Гедранович, И.Н. Тонкович. –2-е изд., стереотип. –Минск: Изд-во МИУ, 2011. – 344 с.

  3. Гедранович, В.В. Основы компьютерных информационных технологий: учеб. -метод. комплекс / В.В. Гедранович, Б.А. Гедранович, И.Н. Тонкович. –2-е изд., стереотип. –Минск: Изд-во МИУ, 2011. – 344 с.

  4. Основы информатики и вычислительной техники//URL: http://www.opengl.org.ru/osnovy-informatiki-i-vychislitelnoi-tekhniki/osnovy-informatiki-i-vychislitelnoi-tekhniki-str41.html (Дата обращения: 07.06.2018)

  5. Гедранович, В.В. Основы компьютерных информационных технологий: учеб. -метод. комплекс / В.В. Гедранович, Б.А. Гедранович, И.Н. Тонкович. –2-е изд., стереотип. –Минск: Изд-во МИУ, 2011. – 344 с.

  6. Гедранович, В.В. Основы компьютерных информационных технологий: учеб. -метод. комплекс / В.В. Гедранович, Б.А. Гедранович, И.Н. Тонкович. –2-е изд., стереотип. –Минск: Изд-во МИУ, 2011. – 344 с.

  7. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –26с.

  8. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –30с.

  9. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –27с.

  10. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –37с.

  11. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –45с.

  12. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –192с.

  13. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –119с.

  14. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –92с.

  15. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –104с.

  16. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –194с.

  17. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-6с.

  18. Г.Буч Объектно ориентированный анализ и проектирование с примерами приложений на С++, 2-е изд./Пер.с англ.—СПб.;М.: «Невский Диалект» — «Издательство БИНОМ», 1999г.

  19. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-7с.

  20. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-8с.

  21. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-9с.

  22. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-11с.

  23. В.В.Мухортов,В.Ю.Рылов Объектно-ориентированное программирование, анализ и дизайн: метод. пособие / В.В.Мухортов,В.Ю.Рылов.-Новосибирск: Изд-во Новософт, 2002г.-11с.

  24. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –194с.

  25. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –197с.

  26. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –195с.

  27. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –196с.

  28. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –199с.

  29. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –198с.

  30. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –198с.

  31. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –199с.

  32. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –200с.

  33. Процедурное программирование//URL:https://mydocx.ru/10-47202.html (Дата обращения: 20.06.2018)

  34. Процедурное программирование//URL:https://mydocx.ru/10-47202.html (Дата обращения: 20.06.2018)

  35. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –206с.

  36. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –207с.

  37. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –207с.

  38. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –205с.

  39. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –205с.

  40. История вычислительной техники: учеб. пособие / И.А. Казакова. –Пенза: Изд-во ПГУ, 2011. –206с.

  41. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. - С.33-35

  42. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 37 с.

  43. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. - С.36

  44. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — 25 с.

  45. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 69 с.

  46. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 85 с.

  47. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. – С.39-40

  48. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 39 с.

  49. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 40 с.

  50. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — 36 с.

  51. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — 37 с.

  52. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 91 с.

  53. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — 40 с.

  54. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — С.41-42

  55. Буч Г. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. 2-е изд. - М.: Бином, 1998. - 102 с.

  56. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. – С.366-367

  57. Лафоре Р. Объектно-ориентированное программирование в С++, 4-е изд., Питер, 2004. – С.368

  58. Вайсфельд М. Объектно-ориентированное мышление. — СПб.: Питер, 2014. — С.44-45