описанием вполне определенных динамических объектов - элементов данных, которые обрабатываются во время выполнения программной системы. Набор типов обычно содержит предопределенные типы, такие как INTEGER или CHARACTER, а также пользовательские типы: записи (структуры), указатели, множества (в Pascal), массивы и другие. Понятие типа является семантической концепцией, и каждый тип непосредственно влияет на выполнение программной системы, так как описывает форму объектов, которые система создает и которыми она манипулирует.

Класс как модуль и как тип

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

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

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

Унифицированная система типов

Важным аспектом ОО-подхода является простота и универсальность системы типов, которая строится на основе фундаментального принципа.

Объектный принцип

Каждый объект является экземпляром некоторого класса

Объектный принцип будет распространяться не только на составные объекты, определяемые разработчиками (такие как структуры данных, содержащие несколько полей), но и на базовые объекты - целые и действительные числа, булевы значения и символы, которые будут рассматриваться как экземпляры предопределенных библиотечных классов (INTEGER, REAL, DOUBLE, BOOLEAN, CHARACTER).

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

[x]. Всегда желательно иметь простую и универсальную схему, нежели множество частных случаев. Предлагаемая система типов полностью опирается на понятие класса.

[x]. Описание базовых типов как абстрактных структур данных и далее как классов является простым и естественным. Нетрудно представить, например, определение класса INTEGER с функциональностью включающей арифметические операции, такие как '+', операции сравнения, такие как '=' и ассоциированные свойства, следующие из соответствующих математических аксиом.

[x]. Определение базовых типов как классов позволяет использовать все возможности ОО, главным образом наследование и родовые средства. Если базовые типы не будут классами, то придется вводить ряд ограничений и рассматривать частные случаи.

Пример наследования - классы INTEGER, REAL и DOUBLE могут быть наследниками двух более общих классов; NUMERIC, в котором определены основные арифметические операции ('+', '-', '*'); COMPARABLE, представляющий операции сравнения ('<' и другие). В качестве примера использования универсализации можно рассмотреть родовой класс MATRIX, родовой параметр которого определяет тип элементов матрицы. Экземпляры класса MATRIX [INTEGER] будут целочисленными матрицами, а экземпляры MATRIX [REAL] будут в качестве элементов содержать действительные числа. В качестве комплексного примера одновременного использования наследования и родовых классов можно использовать класс MATRIX [NUMERIC], экземпляры которого могут содержать элементы типа INTEGER или REAL или любого нового типа T, определенного разработчиком как наследника класса NUMERIC.

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

Построение непротиворечивой и универсальной системы типов требует комплексного применения ряда важных ОО-методик, которые будут рассмотрены позже. К их числу относятся расширяемые классы, гарантирующие корректное представление простых значений; инфиксные и префиксные операции, обеспечивающие возможность использования привычного синтаксиса (a < b или -a вместо неуклюжих конструкций a.less_than (b) или a.negated); ограниченная универсализация, необходимая для описания классов, адаптируемых к типам со специфическими операциями. Например, класс MATRIX может представлять целочисленные матрицы, а также матрицы, элементами которых являются числа других типов.

Простой класс

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

Компоненты

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

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату