Лутц М. - Изучаем Python (1077325), страница 123
Текст из файла (страница 123)
С фундаментальной точки зрения, классы — это действительно всего лишь пакеты функций и других имен, которые во многом напоминают модули. Однако автоматический поиск атрибутов в дереве наследования, который мы получаем при использовании классов, обеспечивает возможности по адаптации программного обеспечения более широкие, чем это возможно с помощью модулей и функций. Кроме того, классы представляют собой удобную структуру, обеспечивающую компактное размещение выполняемого кода и переменных, что помогает в отладке.
Например, методы — это обычные функции со специальным первым аргументом, поэтому мы можем подражать некоторым чертам их поведения, вручную передавая объекты для обработки обычным функ- 512 Глава 22. ООП: общая картина циям. Однако участие методов в наследовании классов позволяет нам естественным образом адаптировать существующее программное обеспечение, создавая новые подклассы, определяющие новые методы, вместо того чтобы изменять существующий программный код.
Подобное невозможно в случае с модулями и функциями. В качестве примера предположим, что вас привлекли к реализации приложения базы данных, где хранится информация о служащих. Как программист, использующий объектно-ориентированные особенности языка РуЫтоп, вы могли бы начать работу с реализации общего суперкласса, который определяет поведение, общее для всех категорий служащих в вашей организации: з Общий суперкласс Ф Обюее поведение с1авв Еюр1оуее: Оет соерцтеза1вгу(ве1(); Оет ртнеаатве(ве1().
оет ргоаосе(ве1(): Оет геттге(ве1(); с1авв Епртпеег(Еер1оуее); З Специализированный подкласс оет соаротеба1агу(ве)т): ... Ф Особенная реализзция Поскольку эта версия созротеБа1агу находится в дереве классов ниже, она будет замещать (переопределять) общую версию метода в классе Еар1оуее. Затем можно создать экземпляры разновидностей классов служащих в соответствии с принадлежностью имеющихся служащих классам, чтобы обеспечить корректное поведение: ЬоЬ = Еар1оуее() ее1 = Епртпеег() Ф Поведение по унолчанию Я Особыв правила начисления ззрплзгы Обратите внимание, что существует возможность создавать экземпляры любых классов в дереве, а не только тех, что находятся внизу,— класс, экземпляр которого создается, определяет уровень, откуда будет начинаться поиск атрибутов.
В перспективе эти два объекта экземпляров могли бы быть встроены в больший контейнерный объект (например, в список или в экземпляр другого класса), который представляет отдел или компанию, реализуя идею композиции, упомянутую в начале главы. Когда позднее вам потребуется узнать размер зарплаты этих служащих, их можно будет вычислить в соответствии с правилами классов, Реализовав это общее поведение, можно специализировать его для каждой категории служащих, чтобы отразить отличия разных категорий от стандарта. То есть можно создать подклассы, которые изменяют лишь ту часть поведения, которая отличает их от типового представления служащего, — остальное поведение будет унаследовано от общего класса.
Например, если зарплата инженеров начисляется в соответствии с какими-то особыми правилами (то есть не по почасовому тарифу), в подклассе можно переопределить всего один метод: 513 ООП с высоты 30 000 футов из которых были созданы объекты, благодаря поиску в дереве наследо- вания соврапу = [ЬоЬ, ве1] № Составной обьект Гог евр 1п соврапу; ргтпт евр.совротеЯа1агу() № Вызвать версию метода длл данного обьекта бег ргосеазог(геабег, сопчегтег, игыег) иш!Е т. бата = геабег,гоаб() !г пот бата Ьгеак бата = сопчегтег(бата) игттег.иг11е(бата) Передавая экземпляры классов с необходимыми интерфейсными методами геаб и иг1те, специализированными под различные источники данных, мы можем использовать одну и ту же функцию ргосеааог для работы с любыми источниками данных, как уже существующими, так и с теми, что появятся в будущем: с1азз Неабег: бет геаб(зе1(): бег о(пег(зе)г): ... с1азз ЕТ1еаеабег(Неабег); бет геаб(зе1(): ...
с1азз Воскетаеабег(аеабег) бег геаб(зе11): № Поведение и инструменти ло умолчанию № Чтение из локального файла № Чтение из соквта ргосезаог(е11енеабег(...), Сопчегтег, е11етггттег(...)) ргосеззог(8оскетаеабег(...), Сопчегтег, Тарейштег(..,)) ргосеззог(Етрзеабег(...), Сопчегтег, Хв1вг(тег(...)) Обратите внимание, что список соврапу вз этого примера мог бы сохраняться в файле, чтобы обеспечить постоянное хранение базы данных с информацией О служащих (с помощью мОдуля РтСК1е, представленного в главе 9 в разделе «Использование файлов «).
Кроме того, в состав Ру1)топ входит модуль апе1че, который мог бы позволить сохранять экземпляры классов в файлах с доступом по ключу, — сторонняя разработка, система ЕОТ)В, позволяет реализовать то же самое, но имеет более качественную поддержку объектно-ориентированных баз данных для промышленного использования. Это еще одна разновидность полиморфизма — идеи, которая была представлена в главе 4 и повторно рассматривалась в главе 15. Вспомните, полиморфизм означает, что смысл операции зависит от объекта, над которым она выполняется.
Здесь метод совротеЯа1а ту определяется в ходе поиска в каждом объекте в дереве наследования, прежде чем он будет вызван. В других приложениях полиморфизм может также использоваться для сокрытия (то есть для инкапсуляции) различий интерфейсов. Например, программа, которая обрабатывает потоки данных, может работать с объектами, имеющими методы ввода и вывода, не заботясь о том, что эти методы делают в действительности: Глава 22, ООП: общая картина Кроме того, благодаря тому, что внутренняя реализация этих методов геаз и нг!ге была разделена по типам источников данных, их можно изменять, не трогая программный код, подобный приведенному, который использует их.
Фактически функция огосеввог сама может быть классом, реализующим логику работы функции преобразования сопчеггег, которую могут унаследовать подклассы, и позволяющим встраивать экземпляры, выполняющие чтение и запись, в соответствии с принципом композиции (далее в этой части книги будет показано, как это реализуется). Когда вы привыкнете программировать в этом стиле (адаптации программного обеспечения), то обнаружите, начиная писать новую программу, что большая часть вашей задачи уже реализована, и ваша задача в основном сводится к тому, чтобы подобрать уже имеющиеся суперклассы, которые реализуют поведение, требуемое вашей программе. Например, возможно, кто-то другой, для совершенно другой программы, уже написал классы Евр1оуее, Яеазег и Хг11ег из данного примера.
В этом случае вы сможете воспользоваться уже готовым программным кодом «за так». На практике во многих прикладных областях вы можете получить или купить коллекции суперклассов, известных как платформы, в которых реализованы наиболее часто встречающиеся задачи программирования на основе классов, готовые к использованию в ваших приложениях. Такие платформы могут предоставлять интерфейсы к базам данных, протоколы тестирования, средства создания графического интерфейса и т. д. В среде такой платформы вам часто будет достаточно создать свой подкласс, добавив в него один-два своих метода, а основная работа будет выполняться классами платформы, расположенными выше в дереве наследования.
Программирование в мире ООП вЂ” это лишь вопрос сборки уже отлаженного программного кода и настройки его путем написания своих собственных подклассов. Безусловно, на то чтобы понять, как использовать классы для достижения такого объектно-ориентированного идеала, потребуется время. На практике ООП влечет за собой большой объем предварительного проектирования, на этапе которого осмысливаются преимущества, получаемые от использования классов; с этой целью программисты начали составлять список наиболее часто встречающихся решений в ООП, известных как шаблоны проектирования — помогающих решать проблемы проектирования.
При этом объектно-ориентированный программный код на языке настолько прост, что он сам по себе не будет препятствием в освоении ООП. Чтобы убедиться в этом, вам следует перейти к главе 23. В заключение В заключение В этой главе мы в общих чертах рассмотрели ООП и классы, получив представление о них, прежде чем углубиться в детали синтаксиса. Как мы узнали, основу ООП составляет поиск атрибутов в дереве связанных объектов; мы называем его поиском в дереве наследования.
Объекты в нижней части дерева наследуют атрибуты объектов, расположенных в дереве выше, — эта особенность позволяет создавать программы за счет адаптации программного кода, а не за счет его изменения или создания нового кода. При грамотном использовании эта модель программирования может привести к существенному сокращению времени, необходимого на разработку.
В следующей главе мы приступим к рассмотрению подробностей, стоящих за общей картиной, рассмотренной здесь. Мы начнем углубляться в изучение классов, однако не стоит забывать, что объектноориентированная модель в языке РуФЬоп очень проста — как я уже заметил, она, по сути, сводится к поиску атрибутов в деревьях объектов.
Прежде чем двинуться дальше, ответьте на контрольные вопросы, чтобы освежить в памяти все то, о чем рассказывалось здесь. Закрепление пройденного Контрольные вопросы 1. Каково основное назначение ООП в языке РуФЬоп? 2. Где выполняется поиск унаследованных атрибутов7 3. В чем разница между объектом класса и объектом экземпляра? 4. В чем состоит особенность первого аргумента в методах классов7 5. Для чего служит метод заза 7 6. Как создать экземпляр класса7 7.
Как создать класс7 8. Как определяются суперклассы для класса7 Ответы 1. Основное назначение ООП состоит в том, чтобы обеспечить многократное использование программного кода, — программный код разлагается на составляющие, чтобы снизить его избыточность, и при создании новых программ выполняется адаптация имеющегося программного кода, а не изменение существующего или создание нового кода. 2. Поиск унаследованных атрибутов выполняется сначала в объекте экземпляра, затем в классе, из которого был создан экземпляр, затем во всех суперклассах, в направлении снизу вверх и слева напра- 576 Глава 22, ООП: общая картина во в дереве объектов (по умолчанию). Как только будет найдено первое вхождение атрибута, поиск прекращается. Поскольку результатом поиска является самая нижняя версия имени из имеющихся в дереве, иерархия классов естественным образом поддерживает возможность адаптации за счет создания подклассов.