Содержание к диссертации
Введение
1 Анализ парадигм 23
1.1 Анализ технологий и классической объектно-ориентированной парадигмы 23
1.1.1 CASE-технологии и графические нотации 23
1.1.2 Среды исполнения 24
1.1.3 Технологии программирования 25
1.1.4 Технологии управления данными 30
1.1.5 Объектно-ориентированные и интеллектуальные базы данных 31
1.1.6 Языки запросов 33
1.1.7 Теоретические препятствия в развитии объектно-ориентированных технологий 33
1.1.8 Предшественники объединенной парадигмы 35
Выводы 38
1.2 Модели данных 38
1.2.1 Диаграмма «Сущность-связь» Чена 38
1.2.2 Связи в объектно-ориентированных базах данных 40
1.2.3 ER-диаграммы для представления объектно-ориентированных связей 40
1.2.4 Модели данных в унифицированном языке моделирования (UML) 40
1.2.5 Объектно-ориентированные языки программирования 41
1.2.6 Модель RM/T 41
1.2.7 Множественное представление 41
Выводы 42
1.3 Объектно-ориентированное программирование и базы данных 42
1.3.1 Аналогии между элементами баз данных и объектно-ориентированного программирования 44
1.3.2 Триггеры и события 46
1.3.3 Наследование, агрегация и реляционные отношения 47
1.3.4 Элементы СУБД, отсутствующие в объектно-ориентированном
программировании 48
Выводы 49
1.4 Распределенные информационные системы 50
1.5 Системы с эволюцией структуры 52
1.5.1 Исторический обзор 52
1.5.2 Элементы объектно-ориентированного программирования 53
1.5.3 Динамизм баз данных 54
1.5.4 Расширение объектно-ориентированной парадигмы принципом динамизма 54
Выводы 55
1.6 Интеллектуальные информационные системы 55
1.6.1 Технологии управления данными и программирования 56
1.6.2 Объектно-ориентированный подход и парадигмы искусственного интеллекта 56
1.6.3 Семантические сети 57
1.6.4 Язык интеллектуальных запросов 58
1.6.5 Распределенные интеллектуальные системы, мобильные и интеллектуальные агенты 59
1.6.6 Эволюция структуры программы 59
1.6.7 Нечеткие технологии 60
Выводы 60
Выводы 61
2 Объединенная парадигма 63
2.1 Общие сведения об объединенной парадигме 63
2.2 Взаимоотношения с другими парадигмами 67
2.2.1 ООП как надстройка 68
2.2.2 Другие парадигмы как надстройки над ООП 68
2.2.3 Элементы, реализующие другие парадигмы как объекты 70
2.3 Принцип реализации полноты парадигмы 70
2.3.1 Главные элементы 70
2.3.2 Обязательное наследование и метаклассирование 70
2.3.3 Полная реализация концепции "класс-это тоже объект" 71
2.3.4 Дуализм классов и экземпляров классов 71
2.3.5 Обязательная агрегация 72
2.4 Динамизм структуры 72
2.5 Абстракция и инкапсуляция 72
2.5.1 Предпосылки введения понятия «паттерн» 74
2.5.2 Определение паттерна и его использование 77
2.5.3 Расширенные объекты 78
2.5.4 Расширенная модель атрибута 81
2.6 Полиморфизм 82
2.6.1 Указатели (ссылки) на паттерны 83
2.6.2 Дуализм объектов и связей 83
2.6.3 Полиморфизм представлений 83
2.6.4 Полиморфизм использования 84
2.6.5 Модель связи 84
2.6.6 Значения по умолчанию как свойства класса 85
2.7 Новая модель информационной системы, анализ и проектирование информационных систем 85
2.7.1 Описание модели 85
2.7.2 Примеры из современных предметных областей 86
2.7.3 Анализ и проектирование в соответствии с объединенной парадигмой 87
2.7.4 Польза элементов объединенной парадигмы 90
Выводы 93
3 Графическая и текстовая нотация 95
3.1 Принципы построения нотаций 95
3.2 Диаграммы паттернов 96
3.2.1 Вложенные паттерны 96
3.2.2 Связи между паттернами 98
3.2.3 Связи как интерфейсы 102
3.2.4 Ограничения на количество экземпляров 104
3.2.5 Указатели на паттерн для реализации параметрического полиморфизма. 106
3.2.6 Паттерны-функции 107
3.2.7 Триггеры 109
3.2.8 Принадлежность объекта нескольким классам 111
3.3 Дополнительные элементы текстовой нотации 112
3.3.1 Автоэкземпляризация 113
3.3.2 Параметризованные классы как паттерны 114
3.3.3 Расширенные объекты 114
3.3.4 Архитектура «Элементы программы как объекты» 116
3.3.5 Транзакции... 117
3.3.6 Динамизм структуры паттерна 118
3.3.7 Полиморфизм использования объектов 118
3.4 НФБ Паттерна 121
Выводы 123
4 Математические основы технологии 124
4.1 Операции над паттернами 124
4.1.1 Принципы построения операций 124
4.1.2 Описание операций 125
Выводы 130
4.2 Анализ сложности систем 131
4.2.1 Виды оценок качества ПО 131
4.2.2 Элементарные характеристики паттернов 134
3.2.1 Составные характеристики паттернов 136
4.2.1 Предельные и средние характеристики паттернов 136
4.2.2 Обобщенные характеристики 137
4.2.3 Характеристики сложности структуры на основе сходящихся рядов 138
Выводы 139
Выводы 140
5 Практическая реализация и алгоритм преобразования паттернов в объектную структуру 141
5.1 Описание программы «Patterns» 141
5.2 Руководство пользователя 142
5.3 Разработка стандартных C++ программ , 146
5.3.1 Класс со свойствами 146
5.3.2 Функции 147
5.3.3 Наследование 148
5.3.4. Структуры 149
5.4 Особые случаи 150
5.4.1 Многоуровневая экземпляризация 150
5.4.2 Принадлежность объекта нескольким классам 151
5.4.3 Взаимное наследование 152
5.4.4 Сложная связь 153
5.4.5 Паттерн - класс, функция и связь 155
5.4.6 Класс - свойство 156
5.4.7 Класс внутри структурного блока 157
5.5 Примеры 158
5.5.1 Большой абстрактный пример 158
5.5.2 Пример паттерна «административная единица» 161
5.5.3 Сравнение текстовой нотации и кода C++ 165
5.6 Алгоритм преобразования структуры Patterns в C++ 165
Выводы 179
Заключение
- Анализ технологий и классической объектно-ориентированной парадигмы
- Общие сведения об объединенной парадигме
- Ограничения на количество экземпляров
- Принципы построения операций
Введение к работе
Актуальность темы исследования 10
Цель и задачи диссертационной работы 15
Область исследования 16
Методика исследования 18
Научная новизна 18
Практическая и теоретическая ценность, внедрение 19
Результаты, выносимые на защиту, авторский вклад 20
Достоверность и обоснованность работы 21
Апробация результатов работы, публикации 21
Структура диссертации 21
1 АНАЛИЗ ПАРАДИГМ 23
1.1 Анализ технологий и классической объектно-ориентированной парадигмы 23
CASE-технологии и графические нотации 23
Среды исполнения 24
Технологии программирования 25
Технологии управления данными 30
Объектно-ориентированные и интеллектуальные базы данных 31
Языки запросов 33
Теоретические препятствия в развитии объектно-ориентированных технологий 33
Предшественники объединенной парадигмы 35
Выводы 38
1.2 Модели данных 38
Диаграмма «Сущность-связь» Чена 38
Связи в объектно-ориентированных базах данных 40
ER-диаграммы для представления объектно-ориентированных связей 40
Модели данных в унифицированном языке моделирования (UML) 40
Объектно-ориентированные языки программирования 41
Модель RM/T 41
Множественное представление 41
Выводы 42
1.3 Объектно-ориентированное программирование и базы данных 42
Аналогии между элементами баз данных и объектно-ориентированного программирования 44
Триггеры и события 46
Наследование, агрегация и реляционные отношения 47
Элементы СУБД, отсутствующие в объектно-ориентированном
программировании 48
Выводы 49
Распределенные информационные системы 50
Системы с эволюцией структуры 52
Анализ технологий и классической объектно-ориентированной парадигмы
Рассмотрим CASE средства, языки программирования и среды исполнения с точки зрения их соответствия ООП и особенностям современных ИС. Обоснование их выбора см. в пункте 0.4.. При этом будем выделять только основные достоинства и недостатки, имеющие отношение к ООП и опустим многочисленные технические характеристики, то есть остановимся на логическом и концептуальном уровне.
Достоинства и недостатки CASE- технологий и графических нотаций приведены в Табл. 1. Более подробный анализ диаграмм «Сущность-связь» Чена, Буча, Рамбо, ОМТ, Шлайера-Меллора см. в пункте 1.2. В данной работе при построении диаграммы классов будет положен принцип включения элементов различных технологий. CASE-технологии описаны в работах [47, 52], достаточно полный обзор различных методов проектирования и требования к идеальному объектно-ориентированному средству изложены в [55, 48]. О примере отечественного средства визуализации см. [106].
Для построения объединенной парадигмой особенности сред исполнения не являются принципиальными и их достоинства и недостатки имеют технический характер, поэтому их детальное рассмотрение выходит за пределы данной работы. Приведенные в параграфе «Объекты исследования» технологии работают непосредственно под управлением операционных систем (ОС) или опосредованно через виртуальные машины или СУБД (Virtual Java Mashine, СУБД Oracle, платформа .NET). Нужно отметить, что работа непосредственно под управлением ОС не позволяет в полной мере создавать приложения с изменяемой структурой.
Классифицируем технологии программирования, как показано в Табл. 2. В основу классификации положим следующие принципы:
1. Технологии классифицируются по парадигмам программирования.
2. Для каждой парадигмы выбирается наиболее распространенный язык программирования. Как правило, такой язык совмещает в себе несколько парадигм программирования в виде иерархических надстроек. Такой язык представляет интерес для данного исследования с точки зрения удобства программирования.
3. Парадигмы программирования расположены в таком порядке, чтобы наиболее распространенный язык реализовывал иерархию парадигм, расположенных до него в верхней части таблицы. Такое расположение парадигм отчасти соответствует их историческому появлению. Так, например, программа на HTML + Javascript представляет собой теги, описывающие web-страницу, в которую встроена программа на объектно-ориентированном языке, методы которой представляют функции, реализующие структурную парадигму. При этом каждый структурный блок представляет собой последовательность математических и логических операторов. Исключение из последовательности парадигм составляет имитационная парадигма, которая появилась раньше объектно-ориентированной (язык Simula - первый объектно-ориентированный язык).
4. Для каждой парадигмы выбирается язык программирования, в наиболее чистом виде представляющий данную парадигму. Такой язык представляет теоретический интерес для построения объединенной парадигмы.
5. Популярность объектно-ориентированного подхода привела к построению смешанных объектно-ориентированных технологий и технологий других парадигм. В колонке 4 Табл. 2 приведены языки, в которых совмещается объектно-ориентированное программирование с другими парадигмами. Как правило, это языки, представляющие собой надстройку над чистыми языками, или подвергшиеся значительному влиянию со стороны чистых языков.
6. С 2000г. появляются коммерческие версии технологий, совмещающие языки программирования и принципы баз данных. Основной их чертой является перманентность объектов. Как правило, такие технологии являются потомками не-. скольких языков программирования, совместимы с C++, Java, наиболее распространенными базами данных (колонка 5). Обзор написан по [27].
Первым объектно-ориентированным языком программирования считается Simula, предназначенным для имитационного моделирования. В нем присутствуют понятия класса и наследования. Уже вторая версия языка сделала его языком общего назначения, причем особенности языка, связанные с моделированием были выделены в классы, от которых производилось наследование. Подход к реализации особых воз можностей системы путем наследования от базовых классов стал традиционным в языках семейства C++, однако он не является единственно возможным (вызов методов служебных классов из Smalltalk).
Распространенность объектно-ориентированного программирования связана во многом с тем, что оно естественным образом представляет мыслительные конструкции человека в программном коде. Поэтому происходит надстройка языков, представляющих другие парадигмы, объектно-ориентированными конструкциями. Широкое распространение языков семейства C++ связано с тем, что они представляют собой ряд надстроек над бывшими в свое время популярными парадигмами. На нижнем уровне это математико-логическая парадигма с остатками ассемблерных конструкций и операциями над указателями (от последних старательно избавились в Java и С#), затем идет уровень структурного программирования, затем - функционального и только на верхнем уровне - объектно-ориентированного. Java и С# устраняют такую важную особенность C++ как множественное наследование, которая заменяется наследованием интерфейсов, но в то же время включают рефлексию типов.
Другое направление связано с надстройками над функциональными языками (многочисленные надстройки над диалектами Lisp, наиболее распространенная -CLOS). В отличие от семейства C++ оно содержит два хорошо интегрированных уровня - функциональный и объектно-ориентированный. Преимуществом данного семейства языков является гибкость конструкций и изменяемость структуры программы. Эти преимущества (добавление и удаление методов и свойств, создание класса во время выполнения программы) появляются в С# традиционным путем наследования от базовых классов.
Язык Smalltalk считается чистым объектно-ориентированным языком, в котором присутствует гибкость, присущая Lisp. Интересен подход, в котором конструкции структурного программирования реализуются в виде вызова методов у служебных классов. Важным дополнением к ООП у Smalltalk является концепция метаклассов, которая, впрочем, не реализована полностью (то есть нет неограниченной цепочки метаклассирования). Эта концепция родственна прототипизации в Java.
Общие сведения об объединенной парадигме
В начале приведем общие сведения об объединенной парадигме в сводном виде (Табл. 7). Новые положения сгруппированы по шести принципам. Три принципа взяты из классической объектно-ориентированной парадигмы (абстракция, инкапсуляция, полиморфизм) (они исследуются в работе [1.10], глубокий анализ проведен в [34]). Три других предлагается ввести в данной работе. Рассмотрим их с точки зрения концепции.
Принцип динамизма возникает из потребности в том, что современные приложения являются развивающимися, и их структура может быть изменена. Его можно сформулировать следующим образом: «Любой элемент программы, относящийся к объектно-ориентированному подходу, может быть изменен в процессе функционирования программы». Подобная свобода изменения структуры также должна предусматривать защитные механизмы.
Введение принципа взаимодействия с другими парадигмами связано с тем, что, как правило, не бывает программ, которые были бы написаны в рамках одного подхода. Обычно программа представляет собой синтез объектно-ориентированной, процедурной, структурной и математико-логической парадигм. Принцип взаимодействия означает, что ООП должна быть независимой надстройкой над кодом, написанным в рамках как можно большего числа парадигм, кроме того код программы в рамках ООП может быть частью программы, написанной по принципам другой парадигмы. То есть программа представляет собой слои различных парадигм, причем парадигмы в разных слоях могут повторяться.
Принцип полноты реализации парадигмы заключается в том, чтобы определить, насколько полно какой-либо элемент программы является объектно-ориентированным. Например, является ли обязательным наследования от какого-либо базового класса.
Данный параграф основан на работах Прохорова В.В. [21,23,22,24].
Исторически в наиболее распространенных языках программирования происходила следующая последовательность смены парадигм программирования: ассемблерные языки, структурное программирование, процедурное программирование, объектно-ориентированные языки (ООП в чистом виде в Simula появился раньше структурного программирования). Если мы попытаемся построить общую модель перехода, то сперва была построена надстройка над условиями и переходами (структурное программирование), затем над операциями (процедурное программирование), затем над данными и адресами (объектно-ориентированное). При этом метки полностью исключались в структурном программировании либо превращались в имена в объектно-ориентированном. Алгоритм представлял собой последовательность действий с одним управлением. В стороне от этого процесса стояли событийная парадигма, многопоточная, нейронные сети и специализированные языки. Затем событийная и многопоточная парадигмы стали описываться в терминах объектов не очень элегантным способом (вместо изменения природы объектно-ориентированного программирования были созданы вспомогательные классы, и описание свелось к наследованию -стандартный способ решения проблем в объектно-ориентированных языках). Аналогично операции манипулирования данными из баз данных решаются в языках ООП с помощью объектов - посредников. В настоящее время группой ODMG разработаны варианты расширения C++ и Java языками запросов.
ООП не существует в чистом виде без взаимодействия с другими парадигмами в большинстве языков программирования. Изначально она появилась как надстройка над имитационной парадигмой в языке Simula. В чистом виде она присутствует в языке Smalltalk. В языках семейства C++ она существует как надстройка над программным кодом, написанным по принципам других парадигм. В наиболее распространенном случае ООП является надстройкой над процедурным программированием, которое в свою очередь представляет собой надстройку над структурным кодом (см. Рис. 6) Такая иерархия отражает историческую последовательность появления парадигм. В работе [24] исследуются микроязыки языка Паскаль, выделяется 14 мик-роязыков. Для удобства будем рассматривать только 4 слоя парадигм (язык записи имен и чисел не имеет значения для данного исследования).
Подобная иерархия не является обязательной. Над объектами классов можно осуществлять операции, которые задаются в C++ в виде перегрузки операторов. Предположим, что над классами можно осуществлять математические операции, например, создавать класс, который является суммой двух других классов. Такая операция напоминает множественное наследование. В случае суммирования возникает вопрос, как его осуществлять, если классы имеют элементы с одинаковыми именами. В этом случае можно оставлять в результирующем классе те элементы, которые принадлежат более раннему слагаемому в выражении (некоммутативное сложение) или объединять элементы по принципу union (в данном исследовании предлагается алгебра над паттернами в пункте 4.1.).
Ограничения на количество экземпляров
В приведенных выше диаграммах мы рассмотрели, как обозначаются ограничения на количества элементов в связи. Покажем, как обозначаются еще два вида ограничений: на количество экземпляров класса и структурные ограничения (см. Рис. 17) (об ограничениях в упрощенной объектно-ориентированной модели см. [112]).
Ограничения на общее количество экземпляров класса показано после наименования класса. Структурные ограничения являются обобщением виртуального наследования и показывают, какое количество экземпляров одного класса могут соединяться между собой посредством цепочки связей. Они обозначаются ключевым словом restriction. Пример текстовой нотации представлен на
Листинг 15, НФБ - на Листинг 16. В данном примере три класса наследуют методы и свойства друг друга, при этом объединяясь в тройки. Ограничения запрещают существование бесконечных цепочек из экземпляров этих трех классов.
Листинг 16. НФБ для классов с ограничениями. паттерн с ограничениями ::= class имя паттерна [ [ максимальное кол-во экземпляров ] ] {...restriction ( имя связи 1 , имя связи 2 ,..., имя связи п ) [ максимальное кол-во экземпляров ]};
Диаграмма на Рис. 18. приводит пример класса с параметром, также на диаграмме реализован принцип обязательного метакласса. На диаграмме классы А, В и С являются экземплярами метакласса, на него также указывает свойство Р класса А. Класс В устанавливает параметрическое наследование. Функции и процедуры обобщаются с классами в понятие паттерн с помощью ключевых слов in, out, inout обозначающих входные, выходные переменные и входные переменные, которые после применения к ним функции изменяют свое значение, и исполняемого блока main.
Пример простейшего паттерна, ведущего себя как класс, процедура и автомат, приведен на Рис. 19, ему соответствует Листинг 19. Экземпляры этого паттерна возвращают две величины: сумму входных переменных, сумму входных переменных и автоматного состояния вместо одной из входных переменных. Кроме того, паттерн запоминает количество вызовов всех его экземпляров.
При таком определении паттерна возможно существование нескольких уровней статичности, многоуровневая экземпляризация и использование функции в различных контекстах.
Мы сделали возможным, введя функцию main в определение класса, поведение экземпляра класса как функции, и возможность использования функции как класса. Введение в C++ Builder понятия свойства вместо обычного поля с методами чтения и записи уменьшило разницу между полями и методами. Это позволит не только хранить данные и код вместе (принцип инкапсуляции) объектно-ориентированного программирования, но и устранить различия между данными и выполняемым кодом. На настоящий момент класс от функции отличает наличие конструктора, деструктора, главной функции main, части, исполняемой в смысле структурного программирования. Свойство от функции отличается наличием функции для чтения и записи, значение по умолчанию можно считать конструктором.
Принципы построения операций
Параметризованные классы с использованием указателей на класс приведены в пункте 3.2.5. Использование паттернов и метаклассов позволяет определять функции, создающие классы (пример см. на Листинг 28).
Листинг 28. Паттерн, порождающий классы class Т {// паттерн - функция, порождающая классы in class tin; // входной класс - параметр private class t; // внутренний класс-параметр main {t = tin}; // инициализация внутреннего класса-параметра }; T(tin = int) Arrayint {public t array[5];}; // вызов функции-паттерна с параметром int, экземпляризация его под именем Arrayint и использование Arrayint в качестве класса с добавлением массива. Arrayint I; // экземпляризация созданного класса for(i=0;i 5;i++) // заполнение массива значениями { I.array[l] = i;}
На Листинг 29 приведен пример формирования и использования экземпляризи-руемого объекта, являющегося экземпляром двух связанных между собой паттернов-классов и выборки из множества экземпляров третьего паттерна-класса, составленной по правилам, аналогичным использованию SQL, модифицированного именованными связями.
Листинг 29. Пример расширенного объекта. // определение паттернов, на основе которых формируется расширенный объект class A{public int а}; class В{ public int b}; class С і connect agregate A[l]; B[l]; }c; class D{inti,j;}; // определение расширенного объекта А, В, D // расширенный объект является экземпляром трех паттернов-классов одновременно where connected А, В by с, // объекты классов А и В связаны объектом с where D.i = 1, // в расширенный объект входят все экземпляры D со свойством і = 1; having D.j avg(D.j) // и свойством j больше среднего. If ExtObj // имя расширенного объекта { public static int seo; public int eo; }; // расширенный объект имеет дополнительное свойство ео. // использование расширенного объекта ExtObj.a=l; ExtObj.b = 2; ExtObj.b.a = 3; // эквивалентно ExtObj.a = 3; ExtObj.seo = 4; ExtObj.і = 5; // у всех экземпляров D, входящих в ExtObj свойство і = 5 ExtObj ExtObjExamle; // экземпляризация ExtObj ExtObjExamle.eo = 6;
Данный пример показывает, что разработанная нотация интегрирует SQL, се Iі мантические связи и вычислительный алгоритм, но является недостаточной для реа лизации идей расширенных объектов объединенной парадигмы, так как в случае распределенности системы и разработки системы несколькими программистами не известно точное количество классов связей, связывающих объект. То есть приведенный аппарат позволяет формировать объекты по конкретным связям, но нет возможности строить расширение объекта по всем связям одновременно.
Проблема решается введением ключевого слова any (любой) и использованием указателей на классы (паттерны). Пример формирования объектов с использованием any приведен на Листинг
Листинг 30. Параметрический полиморфизм в запросах class Х, Y, Z; // указатели на паттерны, используемые как переменные величины при поиске. select A, any X connected by any Y // Выбрать экземпляры А и все экземпляры любого паттерна-класса, соединенные с экземплярами А любой связью select A connected with A by any X // Выбрать экземпляры А, соединенные с экземплярами того же паттерна-класса любой связью select А, В connected by any Y // выбрать экземпляры паттернов-классов А и В, соединенные любой связью Z2 = select any X, any Y connected by any Z // сформировать объекты из любых пар объектов, соединенных любыми связями select А, В connected by Z2 // выбрать объекты паттернов-классов А и В, соединенных цепочками из двух взаимосвязанных связей і select А, В, Z connected by Z // выбрать связанные объекты паттернов-классов А и В и все объекты, которые их связывают Z = select any X, any Y connected by Z // рекурсивный запрос, формирующий цепочки любой длины из взаимосвязанных объектов select А, В connected by Z // выбрать экземпляры А и В, связанные цепочками любой длины select А, В, Z connected by Z // выбрать экземпляры А и В, связанные цепочками любой длины и сами цепочки.
Архитектуру «элементы программы как объекты» можно применить для организации транзакций. Результаты выполнения именованных блоков структурного программирования после их исполнения можно отменить, используя метод rollback (см. пример на Листинг 34.) Листинг 34. Именованный блок как транзакция a=l; F: for(i=0;i 4;i++) {a = a i;} cout« a // результат 24 t F.rollback; cout« a // a = Помимо возможностей пункта 2.3.4. в объединенной парадигме должны существовать возможности для добавления, удаления и модификации атрибутов. Введем операторы add, modify и delete по аналогии с языком С# для добавления, изменения и удаления атрибутов соответственно. Пример их использования приведен в Листинг 35. Листинг 35. Изменение структуры паттерна. class А і х public int a, b; after modify {cout« structure change ;} // триггер после изменения структуры }; A.delete(a); // удаление атрибута A.modify(b = float()); // b изменил тип на float A.add(int d); // к классу А добавился атрибут
Данный полиморфизм предполагает использование объектов в максимально возможных контекстах (см. пункт 2.6.4.). Для этого можно использовать перегрузку свойства main. В Листинг 36 приведен пример использования экземпляра класса в качестве условия. Для данного полиморфизма необходимо ввести в стандарт булев тип данных, который фактически введен во всех компиляторах.