Понятие «абстракция» и понятие «объявление»
Диалог:
[Преподаватель]: Абстракцию данных изучали?
[Я]: А подробнее, что именно?
[Преподаватель]: Абстракция - это отделение кода от заголовков. С оставлением прототипов заголовков в файле .h и вынесением всей реализации в .cpp.
[Я]: Вряд ли можно назвать это абстракцией. Это мы проходили.
[Одна из студенток]: А как это назвать тогда?
[Я]: Отделение объявления от определения (реализации).
[Преподаватель]: Ну так это и есть абстракция.
[Я]: Абстракция применяется в ООП в другом ключе...
[Преподаватель]: И то, и другое - это абстракция, просто разной направленности.
У меня есть сомнения насчет применения этих двух понятий в одном ключе.
Что вы думаете?
Ответы (3 шт):
Удаляторам и минусаторам настоятельно рекомендую отправиться в комментарии и изложить свои аргументы. А также вспомнить о пирамиде Грэма и ее отношению к дискуссии
В контексте C++ "абстракция" (в рамках студенческого и школьного программирования) имеет вполне четкий смысл - это использование класса с чисто виртуальными методами. В нем интерфейс к объекту действительно отделен от реализации, так как реализацию предоставляет экземпляр-наследник.
Разделение на *.h и *.cpp - это следствие технологического процесса сборки программы на C++ (машины были слабенькие, памяти мало, поэтому появилось стремление сделать компилятор однопроходным. А для этого нужно иметь возможность объявить сущность до ее определения), и смешение его в кучу с настоящей абстракцией из ООП как раз и приводит к запутыванию студентов. В процессе преподавания такое нежелательно.
Почему вынос тел функций в *.cpp не является абстракцией? Да потому что нельзя в двух разных файлах держать функцию с одним и тем же именем - компоновщик будет ругаться, придется изобретать какой-то переключатель или тасовать файлы.
Если зайти на Википедию, то можно обнаружить статью Абстракция данных, где оно определяется как
Абстра́кция в объектно-ориентированном программировании — это использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе. Основная идея состоит в том, чтобы представить объект минимальным набором полей и методов и при этом с достаточной точностью для решаемой задачи.
В разделе ссылок в статье приводится статья Бьерн Страуструп — Абстракция данных в языке С++, где понятие более детально рассматривается в контексте C++ и определяется как
Фундаментальная идея состоит в разделении несущественных деталей реализации подпрограммы и характеристик существенных для для корректного ее использования.
Хотя разделение кода между заголовочными файлами и файлами реализации может быть необходимо при создании абстракций данных, само по себе такое разделение не является средством создания абстракций. Такое разделение существует так как по историческим причинам в С/С++ используется раздельная компиляция с текстовым препроцессором, который на первом этапе собирает из множества текстовых файлов один длинный текст единицы трансляции.
Погуглил толкования на английском, одно из лучших описаний:
Abstraction is one of the key concepts of object-oriented programming (OOP) languages. Its main goal is to handle complexity by hiding unnecessary details from the user.
Вольный перевод:
Абстракция это одно из ключевых понятий в объектно-ориентированном программировании (ООП), чьё основное назначение – помогать справляться со сложностью скрывая ненужные детали от пользователя.
То есть, абстракция прямо вытекает в принципы ООП: наследование, инкапсуляция, полиморфизм. Инкапсуляция зачастую выглядит как классы и объекты, которые могут производить сложную логику предоставляя при этом простой интерфейс. В Си++ этот интерфейс выглядит в виде заголовочных файлов, но это лишь одно из технических воплощений как инкапсуляции, так и абстракции в целом. Инкапсуляция реализована и в виде модификаторов доступа полей в C++, private, protected, которые очень чётко говорят, что является деталями реализации и не должно заботить разработчика-пользователя класса. Но инкапсуляция существует и вне ООП, те же заголовочные файлы были и есть в языке Си, и используются там для тех же целей.
Абстракция также проявляется и в наследовании с полиморфизмом, когда мы можем использовать родительские/абстрактные классы или интерфейсы, и успешно производить какую-то логику с объектами даже не зная их точного типа.