Другие объектно-ориентированные системы программирования
C++ является сейчас наиболее распространенным ООЯ. Однако существуют и другие популярные ООЯ и системы программирования. Здесь мы кратко рассмотрим Eiffel и Smalltalk. 5.4.1. Реализация классов. Определение класса Window на Eiffel мало отличается от соответствующего определения на C++ (сравните с п. 5.3.1): class WINDOW export add_box, add_circle, clear_selections, cut_selections, group_selections, move_selections, redraw_all, select_item, ungroup_selections feature xmin, ymin, xmax, ymax: REAL; Create (x0, y0, width, height: REAL) is body end; add_box (x, y, width, height: REAL) is body end; add_circle (x, y, radius: REAL) is body end; add_to_selections (ashape: SHAPE) is body end; clear_selections is body end; cut_selections is body end; group_selections: Group is body end; move_selections (deltax, deltay: REAL) is body end; redraw_all is body end; select_item (x, y: REAL) is body end; ungroup_selections is body end; end -- class WINDOWВсе свойства (feature) класса (соответствуют членам класса в C++) считаются приватными, если только они не объявлены явно как общедоступные: все общедоступные свойства перечисляются в разделе export. Свойство Create (аналог конструктора класса в C++) всегда является общедоступным. Остальные особенности синтаксиса понятны и без пояснений. Smalltalk является языком интерпретируемого типа: программа в системе Smalltalk не компилируется, а переводится в интерпретируемое специальным интерпретатором внутреннее представление. Это позволило сделать систему Smalltalk интерактивной: программист имеет доступ к программе (может, например, изменять ее) во время ее интерпретации, что очень удобно при разработке и отладке программы, но, как известно, уменьшает ее эффективность, так как интерпретация программы сопряжена с дополнительными накладными расходами. Определение класса Window на Smalltalk имеет следующий вид: class name Window superclass Object instance variables xmin, ymin, xmax, ymax: REAL class methods instantiating createAt aPoint ofWidth: width ofHeigt: heigt instance methods adding shapes addboxAt aPoint ofWidth: width ofHeigt: heigt addCircleAt aPoint ofRadius: radius refreshing window redrawAll manipulating selections clearSelections cutSelections groupSelections moveSelectionsBy: deltaPoint selectItemAt: aPoint ungroupSelections private addToSelections: aShapeВсе классы Smalltalk являются подклассами системного класса Object, что позволяет использовать принадлежащие им по наследованию системные операции системы Smalltalk, определенные в классе Object. Строки в описании класса, выделенные курсивом, определяют категории методов. Они служат только для структурирования набора методов. Методы, включенные в категорию private, являются приватными и не доступны извне класса. Чтобы сделать атрибуты приватными, следует не определять методы для запроса и установки значений атрибутов. В системе Smalltalk определен системный метод @, который объединяет пару числовых значений в одно составное значение. Это позволило вместо двух переменных x и y (координат точки) использовать в нашем примере одну переменную aPoint, представляющую обе координаты точки(x,y). Операция присваивания значения (3,4) переменной aPoint с использованием метода @ имеет вид: aPoint <- 3 @ 4
5.4.2. Порождение объектов. В Eiffel объявление переменной (в этом языке вместо термина "переменная" используется термин сущность (entity)) отделено от порождения соответствующего объекта. Объявление сущности определяет имя, значением которого может быть (объектная) ссылка на объект объявленного типа, но эта ссылка при объявлении получает неопределенное значение (void), т.е. не ссылается ни на какой объект. Пример объявления переменной: w: WINDOW В результате этого объявления создается переменная w, значением которой может быть ссылка на окно, но которая пока не ссылается ни на какое окно. Все объекты Eiffel - динамические: они создаются с помощью операции Create; например, следующий оператор создает окно с соответствующими параметрами и присваивает ссылку на него переменной w: w.Create (0.0, 0.0, 8.5, 11.0); В каждом классе неявно определена операция Create без параметров, которая создает новый объект этого класса с нулевыми значениями его атрибутов. Можно переопределить неявную операцию Create; например, для окон эту операцию можно определить следующим образом:
Кроме операции Create, определена операция создания копий уже существующего объекта - Clone. В Eiffel невозможно явным образом уничтожить объект (в нем отсутствует операция, подобная операции delete в C++). Операция Forget убирает объектную ссылку из соответствующей сущности, но не уничтожает сам объект. Объект, на который нет ни одной объектной ссылки, уничтожается во время "чистки мусора", которая, если она не отключена программистом (для этого имеется специальная системная операция), выполняется автоматически. Все объекты Smalltalk - динамические и размещаются в динамической памяти - куче. Удаление объектов осуществляется автоматически подсистемой чистки мусора. Все переменные не имеют типа и могут содержать объекты любого класса. Порождение объектов осуществляется операцией new, определенной в системном классе Object (все классы Smalltalk - наследники класса Object). Например, порождение окна со стандартными параметрами (определяемыми по умолчанию) осуществляется операцией: w <- Window newОперация new является одним из методов уровня класса. С ее помощью можно определить еще один метод порождения окна (уже с параметрами): w <- Window createAt: 0 @ 0 ofWidth: 8.5 ofHeight: 11.0Этот метод может быть определен следующим образом: class name Window... class methods createAt: aPoint ofWidth: width ofHeigt: heigt | w | w <- self new. w initialize: aPoint ofWidth: width ofHeigt: heigt. |w instance methods initialize: aPoint ofWidth: width ofHeigt: heigt. xmin <- aPoint x. ymin <- aPoint y. xmax <- xmin + width. ymax <- ymin + heightОтметим, что метод уровня класса не имеет непосредственного доступа к атрибутам объектов. Поэтому для инициализации окна потребовалось определить метод уровня объекта initialize. В Eiffel методы называются подпрограммами (routines). При вызове этих подпрограмм им передаются параметры, которые могут иметь простой тип (REAL, INTEGER, BOOLEAN, или CHARACTER) или быть объектами классов, определенных программистом. В подпрограмме не разрешается изменять значения формальных параметров путем присваивания им новых значений или применения к ним операции (такие, как Create, Clone, или Forget), которые могут менять значение объектной ссылки. В то же время остальные операции могут быть применены к объектам, являющимся формальными параметрами, что вызовет изменение состояния указанных объектов.
Синтаксис вызова операции в Eiffel такой же, как в C++, причем операция '.' в Eiffel соответствует операции '->' в C++: local aShape: SHAPE; dx, dy: REAL do... aShape.move (dx, dy); endВ Eiffel определен неявный доступ к свойствам целевого объекта по имени соответствующего свойства. Идентификаторы x и y являются именами атрибутов целевого объекта SHAPE: move (deltax, deltay: REAL) is -- move a shape by delta do x = x + deltax; y = y + deltay endВ Eiffel имеется предопределенный идентификатор Current, который именует целевой объект операции (он аналогичен идентификаторам this в C++ и self в Smalltalk). Поэтому предыдущий фрагмент программы можно записать следующим эквивалентным образом: move (deltax, deltay: REAL) is -- move a shape by delta do Current.x = Current.x + deltax; Current.y = Current.y + deltay endВ Smalltalk все параметры и переменные являются объектами; все операции являются методами, связанными с этими объектами. Применить операцию к объекту - значит послать этому объекту сообщение, состоящее из имени операции и списка значений ее параметров. Сообщение связывается с объектом во время выполнения программы (динамически), рассматривается класс соответствующего объекта и находится соответствующая операция в этом классе или в его предках (по наследованию). Формальные параметры метода запрещено изменять внутри метода с помощью присваиваний. Синтаксис обращения к операции (посылки сообщения) следующий: aShape moveDelta: aPoint Этот метод можно реализовать следующим образом: class name Shape instance variables x y instance methods moveDelta: aPoint x <- x + aPoint x y <- y + aPoint yВнутри метода разрешен непосредственный доступ по имени к атрибутам целевого объекта операции (в Smalltalk атрибуты называются переменными объекта (instance variables)). Как уже упоминалось, в Smalltalk предопределена псевдо-переменная self, именующая целевой объект (получатель сообщения). 5.4.4. Реализация наследования. В Eiffel список наследования помещается вслед за ключевым словом inherit:
Для обозначения абстрактных операций используется ключевое слово deferred; такие операции должны быть реализованы во всех подклассах. Переопределение свойств класса в подклассе отмечается в разделе redefine. В Smalltalk описание класса Item, его подкласса Shape, а также подклассов Box и Circle класса Shape может иметь следующий вид: class name Item superclass Object class name Shape superclass Item instance variables x y instance methods cut draw erase move: aPoint ungroup class name Box superclass Shape instance variables width height instance methods pick: aPoint write: aColor class methods createAt: aPoint width: widthSize length: lengthSize class name Circle superclass Shape instance variables radius instance methods pick: aPoint write: aColor class methods createAt: aPoint radius: radiusSizeВсе атрибуты суперкласса доступны всем его потомкам. Все методы могут быть переопределены в подклассах. Множественное наследование не поддерживается. 5.4.5. Реализация зависимостей. В Eiffel для реализации зависимостей применяются конструкции, аналогичные конструкциям C++. Поддерживаются параметризованные (родовые (generic)) контейнерные объекты (обычно эти объекты параметризуются относительно типов объектов, которые они содержат). Базовая библиотека классов системы Eiffel содержит контейнерный класс LINKED_LIST, который можно использовать для реализации зависимости типа "много к одному" между классами ITEM и GROUP: class ITEM export get_group -- выборочный экспорт в класс GROUP set_group(GROUP), forget_group(GROUP) feature get_group: GROUP is do Result:= mygroup end; set_group(g:GROUP) is do mygroup:= g end; forget_group is do forget(mygroup) end; end --ITEM class GROUP export add_item, remove_item, get_items inherit ITEM feature items: LINKED_LIST[ITEM]; --параметризованный тип Create is do items.Create end; add_item(value:ITEM) is do items.finish; items.insert_right(value); value.set_group(Current) end; remove_item(value:ITEM) is do items.search(value,l); items.delete; value.forget_group end; get_items(number:INTEGER):ITEM is do Result:= items end; end --GROUPEiffel обеспечивает выборочный экспорт относительно любого свойства. В рассматриваемом примере в класс GROUP экспортируются свойства set_group и forget_group класса ITEM. Это поддерживает инкапсуляцию путем ограничения доступа по записи данных в объекты классов, участвующих в зависимости между ITEM и GROUP. Операция forget Eiffel предназначена для освобождения памяти; она освобождает память, занимаемую объектом, который является ее операндом, а также присваивает объектной ссылке неопределенное значение.
В Smalltalk большую часть зависимостей помогает реализовать богатая системная библиотека классов. Например, для реализации зависимости типа "много-к-одному" между графическими объектами (Item) и группой, в которую они входят (Group) можно использовать библиотечный класс Set: class name Item superclass Object class name Shape superclass Item instance variables group instance methods cut draw erase move: aPoint ungroup --дополнительные методы getGroup |group --приватные методы putGroup: aGroup group <- aGroup class name Group superclass Item instance variables items class methods new |((super new)putItems:(Set new)) instance methods pick: aPoint write: aColor addItem: anItem items add: anItem. anItem putGroup: self removeItem items remove: anItem. anItem putGroup: nil getItems |items copy --приватные методы putItems: aSet items <- aSetВвиду того, что в системе Smalltalk не производится контроль типов, нет никаких ограничений на тип объектов, которые можно добавить в группу: любой объект, который соответствует сообщению putGroup:, допустим. Строка приватные методы является комментарием, сообщающим программисту, что методы, перечисленные после этой строки лучше использовать как приватные; если он не последует этому совету, система все равно не зафиксирует ошибку, так как Smalltalk не поддерживает приватности методов и данных, и на самом деле все методы общедоступны.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|