"Structured programming – don’t use unrestrained GOTO;
functional programming – don’t use assignment;
object-oriented programming – don’t use pointers to functions."
Robert C. Martin

Оглавление

  1. Абстрактные типы данных
  2. Сокрытие данных и инкапсуляция
  3. Конструкторы
  4. Перегрузка функций
  5. Перегрузка операторов
  6. Полиморфизм, первая часть
  7. Наследование
  8. Полиморфизм, вторая часть
  9. Шаблоны типов
  10. Полиморфизм, третья часть

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

Для того, чтобы в этом убедиться, достаточно попытаться дать исчерпывающее определение такому простому на первый взгляд понятию как “переменная” в контексте программирования. Кто-то может сказать, что переменная - это имя в программе. Что будет не совсем точно, потому что “имя” в программе обладает единственным свойством – уникальностью в заданном контексте. Очевидно, что переменные обладают и другими свойствами. Кто-то захочет оттолкнуться от математического определения переменной и скажет, что это величина, которая принимает различные значения. Это опять не совсем точно в отношении переменных в программах, так как математическая величина переменная в одном контексте может быть постоянной в другом[1], что в программировании не всегда применимо. Кто-то может предположить, что переменная - это значение, которое приписывается имени в программе. Это тоже будет не совсем точно, так как значение не может существовать в программе само по себе, так как оно абстрактно. Оно будет иметь некоторое конкретное представление, которое хранится где-то в памяти программы. Например, число “42” является идеей – значением, оно будет представлено в памяти в виде двоичного (25 + 23 + 21), а в программе – еще и в виде десятичного (4 * 101 + 2 * 100) или шестнадцатеричного (2 * 161 + 10 * 160, 2А16) набора данных. Для определения переменной этого тоже не достаточно.

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

Во-первых, программа следует определенным правилам, таким как работа с переменными и постоянными значениями, инструкциями, выражениями и т.д. Во-вторых, программа имеет выделенную для нее область памяти, где хранятся все необходимые ей для правильной работы величины. В-третьих, все эти величины имеют за собой абстрактные концепции. Например, абстракция числа “42” выражается в программе в виде какого-то имени, которое указывает на соответствующее значение в памяти. Или наоборот, арифметическое выражение “А + В” отражает взаимодействие двух переменных, каждая из которых имеет определенное значение, но в конечном итоге нас интересует только абстрактный результат. Наконец, более сложное взаимодействие “С = А + В” представляет собой некую абстрактную операцию, которая в программе выражается через последовательное выполнение сначала сложения, а затем присваивания результата сложения переменной.

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

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

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

Предназначение абстракций в программировании заключается в том, чтобы проектировать программы, понимать их и проверять их логику на правильность на основании законов, которые управляют абстракциями (например, на основании законов математики), не отвлекаясь на подробности реализации этих абстракций в конкретном компьютере[4].


 

Источники

  1. Переменные и постоянные величины – такие величины, которые в изучаемом вопросе принимают различные значения или сохраняют одно значение; различие между переменной и постоянной величинами относительно: величина, постоянная в некотором вопросе, может быть переменной в другом; Прохоров, А.М. et al., “Переменные и постоянные величины”, Советский энциклопедический словарь, с. 998.
  2. Strachey, C., “Fundamental Concepts in Programming Languages”, Higher-Order and Symbolic Computation, 13, 2000, p. 13.
  3. Stepanov, A., McJones, P., “Foundations. Values”, Elements of Programming, Semigroup Press, 2019, p. 2.
  4. N. Wirth, “Representation of Arrays, Records, and Sets”, Fundamental Data Structures, Algorithms and Data Structures, 1985, p. 21.

 

Copyright © 2022 Брынзан, Л.В.
GNU General Public License
“Commons Clause” License Condition v1.0
GPL Attribution-ShareAlike 4.0 International