|
Программирование >> Процедурные приложения
Глава 13. Основы ООП Все новое - это хорошо забытое старое C++ и ООП Основная терминология o Инкапсуляция o Иерархия классов Первое знакомство с классом o Структура в роли примитивного класса o Синтаксис описания классов o Простейший класс В данной главе будут рассмотрены основные термины и понятия объектно-ориентированного программирования (ООП). В чем, вообще говоря, особенность объектно-ориентированных языков, таких как C++? Одним словом на этот вопрос можно ответить так: компактность! Методы ООП позволяют лучше организовать и эффективнее использовать все те функции, с которыми вы познакомились в предыдущих главах книги. Если вы новичок в ООП, то основная проблема для вас будет состоять не в освоении каких-то новых ключевых слов, а в изучении принципиально иных подходов к построению и структурированию программ. Единственное серьезное препятствие на вашем пути - это новая терминология. Многие средства процедурного программирования, которые вы изучали до сих пор, в ООП носят другие названия. Например, вы узнаете о превращении знакомого вам понятия структуры в понятие класса - нового типа данных, предназначенного для создания особого рода динамических переменных - объектов. Все новое - это хорошо забытое старое Специалисты по маркетингу хорошо знают, что товар продается лучше, если где-нибудь на упаковке вставить слово новинка . Поэтому не стоит полагать, что ООП является такой уж новой концепцией. Скотт Гудери (ScottGuthery) вообще утверждал в 1989, что ООП берет свое начало с появления подпрограмм в 40-х годах (см. статью Является ли новое платье короля объектно-ориентированным? ( Are the Emperors New Clothes Object Oriented? ), Dr. Dobbs Journal, декабрь, 1989 г.). В этой же статье утверждалось, что объекты, как основа ООП, появились еще в языке FORTRAN II. Если это верно, то почему же об ООП все говорят как о новинке последнего десятилетия нашего века? Все дело в компьютерной технике. Совершенно верно, концепция ООП могла быть сформулирована еще в 40-х годах, но реализовать эту идею в полной мере удалось только в последние десять лет. Первые программы на языке BASIC часто представляли собой многостраничные листинги, в которых не прослеживалось четкой структуры. Огромные программные блоки связывались друг с другом посредством одно- или двухбуквенных меток, по которым осуществлялись переходы с помощью многочисленных команд goto. Ночным кошмаром были анализ и отладка таких программ, не говоря уже об их модификации. Сопровождение их тоже было нелегким делом. В 60-х годах была реализована методика структурного программирования, подразумевавшая использование переменных с осмысленными именами, существование глобальных и локальных переменных и процедурное проектирование приложений по принципу сверху вниз . Благодаря внедрению в жизнь этих концепций тексты программ стали понятнее и читабельнее, в результате чего упростился процесс отладки программ. Стало проще сопровождать программы, так как появилась возможность контролировать выполнение не отдельных команд, а целых процедур. Примерами языков, ориентированных на подобный процедурный подход, могут быть Ada, С и Pascal. Бьярна Страуструпа (Bjarne Stroustrup) можно считать отцом ООП в том виде, в каком эта концепция представлена в языке C++, разработанном им в начале 80-х в компании BellLabs. С точки зрения Джеффа Дантеманна (JeffDuntemann), ООП представляет собой то же структурное программированное, но с еще большей степенью структуризации. Это вторая производная от исходной теории построения программ. (См. статью Лавирование среди айсбергов ( DodgingSteamships ), Dr. DobbsJournal, июль, 1989 г.) Действительно, как вы убедитесь, ООП в C++ в значительной степени основано на концепциях и средствах структурного программирования языка С. И хотя язык C++ ориентирован на работу с объектами, при желании на нем можно писать как традиционные процедурные приложения, так и неструктурированные программы. Выбор за вами. C++ и ООП Все предыдущие главы книги были посвящены изучению методик традиционного структурного программирования. Структура процедурных программ в общем такова: имеется функция main(), а из нее вызываются другие функции программы. Тело функции main(), как правило, невелико. Ее роль обычно сводится к распределению задач между остальными функциями, которые описывают действия, выполняемые над данными. Основным недостатком такого подхода являются проблемы, возникающие при сопровождении программ. Например, если в программу нужно добавить какой-нибудь программный блок, то чаще всего ее приходится полностью перекомпилировать. Это не только отнимает много времени, но и чревато ошибками. В основу ООП заложены совершенно иные принципы и другая стратегия написания программ, что часто становится камнем преткновения для многих разработчиков, привыкших к традиционному программированию. Теперь программы представляют собой алгоритмы, описывающие взаимодействие групп взаимосвязанных объектов. В C++ объекты создаются путем описания класса как нового типа данных. Класс содержит ряд констант и переменных (данных), а также операций (функций-членов, или методов), выполняемых над ними. Чтобы произвести какое-либо действие над данными объекта, ему необходимо, выражаясь в новых терминах, послать сообщение, т.е. вызвать один из его методов. Подразумевается, что к данным, хранящимся в объекте, нельзя получить доступ иначе, как путем вызова того или иного метода. Таким образом, программный код и оперируемые данные объединяются в единой виртуальной структуре. ООП дает программистам три важных преимущества. Первое состоит в упрощении программного кода и улучшении его структуризации. Программы стали проще для чтения и понимания. Код описания классов, как правило, отделен от кода основной части программы, благодаря чему над ними можно работать по отдельности. Второе преимущество заключается в том, что модернизация программ (добавление и удаление программных блоков) становится несравнимо более простой задачей. Чаще всего она сводится к добавлению нового класса, который наследует все свойства одного из имеющихся классов и содержит требуемые дополнительные методы. Третье преимущество состоит в том, что одни и те же классы можно много раз использовать в разных программах. Удачно созданный класс можно сохранить отдельно в библиотечном файле, и его добавление в программу, как правило, не требует внесения серьезных изменений в ее текст. При изучении предыдущих глав книги у вас могло сложиться впечатление, что преобразование текстов программ с языка С на C++ и обратно не составляет труда. Достаточно только поменять некоторые ключевые слова, например printf() на cout. В действительности различия между этими языками гораздо более глубоки и лежат как раз в области ООП. Например, язык С не поддерживает классы. Поэтому преобразовать процедурную программу в объектно-ориентированную намного труднее, чем может показаться. Зачастую проще выбросить старую программу и написать новую с нуля. В отсутствии преемственности между двумя подходами заключается определенный недостаток ООП. Идеи ООП в той или иной форме проявились во всех современных языках. Почему же сейчас мы говорим о C++ как об основном средстве создания объектно-ориентированных программ? Все дело в том, что, в отличие от многих других языков, классы в нем являются особым типом данных, развившимся из типа struct языка С. Кроме того, в C++ добавлены некоторые дополнительные средства создания объектов, которых нет в других языках программирования. В данном контексте в числе преимуществ языка C++ следует указать строгий контроль за типами данных, возможность перегрузки операторов и меньшую зависимость от препроцессора. Хотя объектно-ориентированные программы можно писать и на других языках, только в C++ вы можете в полной мере реализовать всю мощь данной концепции, так как это язык, который не адаптировался к новому веянию, а специально создавался для ООП. Основная терминология Поскольку идея ООП была достаточно глобальной и не связанной с конкретным языком программирования, потребовалось определить термины, общие для всех языков программирования, поддерживающих данную концепцию. То есть те термины, с которыми мы сейчас познакомимся, являются общими как для Pascal, так и для C++ и прочих языков. Впрочем, наряду с общей терминологией существуют и термины, специфичные для отдельных языков. ООП представляет собой уникальный подход к написанию программ, когда задачи и решения формулируются путем описания схемы взаимодействия связанных объектов. С помощью объектов можно смоделировать реальный процесс, а затем проанализировать его программными средствами. Каждый объект является определенной структурой данных, поэтому переменную типа struct в C/C++ можно рассматривать как простейший объект. Взаимодействие между объектами осуществляется путем отправки им сообщений, как уже говорилось ранее. Сообщение по сути своей - это то же, что и вызов функции в процедурном программировании. Когда объект получает сообщение, выполняется хранящийся в нем метод, который возвращает результат вычислений в программу. Методы также называют функциями-членами, и они напоминают обычные функции за тем исключением, что являются неразрывной частью объекта и не могут быть вызваны отдельно от него. Класс языка C++ является расширенным вариантом структуры и служит для создания объектов. Он содержит функции-члены (методы), связанные некоторыми общими атрибутами. Объект - это экземпляр класса, доступный для выполнения над ним требуемых действий. Инкапсуляция Под инкапсуляцией понимается хранение в одной структуре как данных (констант и переменных), так и функций их обработки (методов). Доступ к отдельным частям класса регулируется с помощью специальных ключевых слов public(открытая часть), private(закрытая часть) и protected(защищенная часть). Методы, расположенные в открытой части, формируют интерфейс класса и могут свободно вызываться всеми пользователями класса. Считается, что переменные-члены класса не должны находиться в секции public, но могут существовать интерфейсные методы, позволяющие читать и модифицировать значение каждой переменной. Доступ к закрытой секции класса возможен только из его собственных методов, а к защищенной - также из методов классов-потомков. Иерархия классов В C++ класс выступает в качестве шаблона, на основе которого создаются объекты. От любого класса можно породить один или несколько подклассов, в результате чего сформируется иерархия классов. Родительские классы обычно содержат методы более общего характера, тогда как решение специфических задач поручается производным классам. Наследование Под наследованием понимают передачу данных и методов от родительских классов производным. Если класс наследует свои атрибуты от одного родительского класса, то такое наследование называется одиночным. Если же атрибуты наследуются от нескольких классов, то говорится о множественном наследовании. Наследование является важнейшей концепцией программирования, поскольку позволяет многократно использовать одни; и те же классы, не переписывая их, а лишь подстраивая для решения конкретных задач и расширяя их возможности. Полиморфизм и виртуальные функции Другая важная концепция ООП, связанная с иерархией классов, заключается в возможности послать одинаковое сообщение сразу нескольким классам в иерархии, предоставив им право выбрать, кому из них надлежит его обработать. Это называется полиморфизмом. Методы, содержащиеся в разных классах одной иерархии, но имеющие общее имя и объявленные с ключевым словом virtual, называются виртуальными. Благодаря полиморфизму можно делать в программе запрос к объекту, даже если тип его не известен заранее. В C++ эта возможность реализуется за счет подсистемы позднего связывания, под которым понимается динамическое определение адресов функций во время выполнения программы в противоположность традиционному статическому (раннему)
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |