На этом шаге мы познакомимся с флейверами.
Идея объектно-ориентированного программирования возникла при обработке свойств атомов задолго до того, как языки Simula и Smalltalk появились на свет. Однако в "чистую" парадигму программирования (или в метафору, как это имеет место в языке Smalltalk) она вылилась лишь в ходе развития соответствующих языков программирования. Все же возможности, присущие языку LISP, позволили освоить и включить в него результаты других разработок и часто в более совершенной форме, чем в исходном языке.
В качестве объектной системы, основанной на диалекте muLISP, мы рассмотрим систему Flavors, являющуюся объектно-ориентированным расширением диалекта Common LISP.
В объектном программировании не предполагается, что программа состоит из набора процедур и данных, ее основными составными единицами являются объекты, содержащие как процедуры, так и данные. Идея объединения данных и процедур является основной идеей объектной модели и основой объектного программирования.
Тип объекта часто называют классом объектов (Object Class) или просто классом.
Класс - это множество всех потенциальных объектов, которые могут возникнуть из его определения. Объекты подразделяются на классы в зависимости от присущих им свойств и действий, которыми они обладают. Свойства и действия объектов одного класса одинаковы. Набор свойств объектов разных классов различен, хотя некоторые свойства и действия могут при этом совпадать. Взаимодействие между объектами одного или разных классов определяются на основе присущих классу действий и соответствующих им сообщений.
У объектов нужно различить определение и вызов.
Определение объекта - это абстрактное описание типа объекта, которое представляет все объекты данного типа.
С помощью вызова объекта из определения создаются экземпляры объектов (фактические объекты).
Классу в системе Flavors соответствует понятие флэйвер (Flavor). Однако флэйвер более общее понятие, чем класс языка Smalltalk, т.к. он может представлять и некоторые абстрактные свойства, которые как таковые не могут быть реализованы объектом.
Например, понятие "круглый" нельзя реализовать конкретным самостоятельным объектом. Назовем такие классы характеристическими классами (Mixing Flavor) или классами свойств в отличие от классов объектов, которые назовем естественными классами.
Характеристический класс можно использовать в определении класса объектов для того, чтобы он как бы "ароматизировал" объекты некоторого базового класса объектов (Base Flavor). Объекты можно снабдить разными "оттенками" и "ароматами", вполне аналогично добавлению в пищу разных приправ.
Если у классов объектов можно найти общие свойства, то можно их выделить и определить в виде характеристического класса. Так можно значительно сократить определения классов. Таким образом, характеристический класс является еще одним механизмом абстрагирования данных и действий.
В системе Flavors определение флэйвера имеет следующий вид:
(DEFFLAVOR FLAV VARS INH-FLAVS . OPTIONS)
Форма DEFFLAVOR определяет флэйвер FLAV с надклассами, определенными списком INH-FLAVS, и помещает переменные экземпляра, указанные в списке VARS, в список свойств флэйвера.
Более того, форма DEFFLAVOR создает методы :GET и(или) :SET, если ключевые параметры
:GETTABLE-INSTANCE-VARIABLES и(или) :SETTABLE-INSTANCE-VARIABLES
Например:
; Определение флэйвера с именем ТЕЛО (DEFFLAVOR ТЕЛО ; Имя флэйвера ; --------------------------------------------------- ( (X 0) (Y 0) (ЦЕНТР-X СОЛНЦЕ-X) ; Свойства (ЦЕНТР-Y СОЛНЦЕ-Y) РАДИУС-ОРБИТЫ ; флэйвера (СЛЕД NIL) (УГОЛ 1) СКОРОСТЬ РАЗМЕР ; ) ; --------------------------------------------------- () ; Надклассы ; --------------------------------------------------- (:SETTABLE-INSTANCE-VARIABLES ЦЕНТР-X ЦЕНТР-Y) ; Режимы )
Форма DEFFLAVOR реализована в виде сложного макроса. Побочным эффектом его вызова будет автоматическая генерация необходимых функций доступа, которые можно использовать при чтении и присваивании значений переменным.
Побочным эффектом, возникающим в связи с генерацией объекта, можно управлять посредством следующих, необязательно задаваемых в определении, ключевых параметров (режимов).
:GETTABLE-INSTANCE-VARIABLES
:SETTABLE-INSTANCE-VARIABLES
Методы присваивания значения имеют форму
:SET-x
Например, имя метода, присваиваемого переменной ИМЯ, будет :SET-ИМЯ.
На основе определения флэйвера мы можем создавать новые экземпляры, принадлежащие данному флэйверу. Это осуществляется вызовом макроса
(MAKE-INSTANCE FLAV . VARS)
Например:
(MAKE-INSTANCE ПЛАНЕТА ; Имя флэйвера ; ------------------------------------------ :РАДИУС-ОРБИТЫ 114 ; Присваивание значений :СКОРОСТЬ 0.053 ; свойствам (переменным :РАЗМЕР 4 ; экземпляра) )
Поскольку позже мы хотим сослаться на созданный объект, то присваиваем его значение переменной МАРС:
(SETQ МАРС (MAKE-INSTANCE ПЛАНЕТА :РАДИУС-ОРБИТЫ 114 :СКОРОСТЬ 0.053 :РАЗМЕР 4) )
На следующем шаге мы поговорим о свойствах и методах.