Классы. Статические и динамические сущности
Каждый класс должен иметь декларацию класса и имлементацию. Декларация класса содержит набор объявлений констант, доменов, предикатов. Имплементация класса содержит собственно реализацию предикатов (клаузы).
Cтатический класс - класс не способный порождать объекты (экземпляры или точные копии). Все предикаты и разделы фактов статического класса существуют в единственном экземпляре во всем проекте.
Динамический класс - класс, способный порождать объекты (экземпляры или точные копии), Каждый экземпляр динамического класса содержит свою копию предиката и свою копию раздела фактов. Создание объекта (экземпляра или копии класса) осуществляется вызовом предиката-конструктора. Как правило, это предикат-функция new(), но может быть и любой другой, объявленный как конструктор в разделе constructors декларации класса.
Статический класс - это класс, не имеющий интерфейса. Или, что то же самое, - если класс не имеет инерфейса, то он - статический,
Если класс имеет интерфейс - то он - динамический.
Статические классы Например, класс staticClass является статическим классом.
class staticClass end class staticClass implement staticClass end implement staticClass
но этот класс ничего не способен делать. Чтобы что-то делать, добавим в этот класс декларации предикатов и клаузы.
class staticClass predicates visibleStaticPred:(). end class staticClass implement staticClass clauses visibleStaticPred():- ... invisibleStaticPred(), ... class predicates invisibleStaticPred:(). clauses invisibleStaticPred():- ... end implement staticClass
Обращения к предикатам этого класса записываются как
... staticClass::staticVisiblePred(), ...
(существенно использования именно :: для обращения к статической сущности)
Здесь предикат invisibleStaticPred является предикатом, объявленным внутри имплементации, и только внутри этой имплементации может быть вызван. То есть предикаты, объявленные в декларации класса являются заведомо всегда статическими предикатами, а раздел объявлений предикатов внутри имплементации статического класса всегда должен имет вид
class predicates
Разделы фактов могут быть только в имплементации и для статичесих классов это объявление тоже использует форму
class facts
Если попробовать создать экземпляр класса staticClass с помощью вызова конструктора new()
... staticClass::new(), ...
то это не пропустит компилятор.
Таким образом, статические классы - это просто модули проекта. Проект, построенный только на модулях (статических классах) - не имеет никакого отношения к объекто-ориентированной концепции программирования.
Динамические классы Например, класс dynamicClass является динамическим классом, что определяется конструкцией dynamicClass:justInterface.
class dynamicClass:justInterface end class dynamicClass implement dynamicClass end implement dynamicClass interface justInterface end interface justInterface
Опять-таки, синтаксически все правильно, но практически бесполезно. Теперь добавим какие-нибудь полезности и вынесем вперед декларацию интерфейса.
interface justInterface predicates visibleDynamicPred:(). end interface justInterface class dynamicClass:justInterface predicates visibleStaticPred:(). end class dynamicClass implement dynamicClass clauses visibleStaticPred():- ... invisibleStaticPred(), ... clauses visibleDynamicPred():- ... invisibleStaticPred(), ... class predicates invisibleStaticPred:(). clauses invisibleStaticPred():- ... predicates invisibleDynamicPred:(). clauses invisibleDynamicPred():- ... end implement dynamicClass
Здесь мы имеем четыре предиката, которые имеют различные динамические особенности.
visibleDynamicPred - динамический предикат, принадлежащий интерфесу justInterface, видимый извне. visibleStaticPred - статический предикат, видимый извне. invisibleStaticPred - статический предикат, определенный в имплементации класса dynamicClass, невидимый извне. invisibleDynamicPred - динамический предикат, определенный в имплементации класса dynamicClass, невидимый извне.
Похожим образом внутри имплементации декларируются статические и динамические разделы фактов.
К такому классу можно обратиться как к статическому
... dynamicClass::visibleStaticPred(), ...
но нельзя так:
... dynamicClass::visibleDynamicPred(), ...
Чтобы вызвать предикат visibleDynamicPred(), необходимо с помощью конструктора создать экземпляр класса и обратиться к этому экземпляру:
... ЭкземплярDynamicClass=DynamicClass::new(), ЭкземплярDynamicClass:visibleDynamicPred(), ...
Примечания: a) Конструктор new() является предопределенным конструктором, объявление которого не требуется; B) В обращении к экземпляру класса (объекту) используется разделитель ':' (а не '::', как этого требует обращение к статической сущности);