Основы объектно-ориентированного программирования

         

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


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

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

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

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

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

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

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


Содержание раздела