Фэндом

Smalltalk по-русски

Смолток. Язык и его реализация/Первая часть/5. Метаклассы

< Смолток. Язык и его реализация | Первая часть

239статей на
этой вики
Добавить новую страницу
Обсуждение0 Поделиться
5.0.jpg

МетаклассыПравить

Т.к. все компоненты системы Смолток представляются объектами и все объекты это экземпляры класса, сами классы должны быть представлены экземплярами класса. Класс чьи экземпляры сами являются классами называются метаклассами. Эта глава описывает специальные свойства метаклассов. Примеры показывают как используются метаклассы для создания экземпляров и общих запросов к классам. В ранних версиях системы Смолток был только один метакласс называемый Класс. Он отвечал за организацию класса показанную на рисунке 5.1. Как и в главе 4 прямоугольники обозначают классы а кружки обозначают экземпляры класса в котором они содержатся. Там где возможно прямоугольники обозначаются с помощью имени класса. Заметьте что есть по одному кружку в прямоугольнике Класс для каждого прямоугольника на рисунке.

5.1.jpg

Рисунок 5.1

При данном подходе возникают трудности т.к. протокол сообщений всех классов должен быть одинаковым т.к. он определён в одном месте. Практически сообщения используемые для создания новых экземпляров были одними и теми же для всех классов и не могли произвести специальной инициализации. С одним метаклассом, все классы отвечали на сообщение новый или новый: возвращая экземпляр чьи переменные ссылались на пусто. Для большинства объектов пусто это не подходящее значение переменной экземпляра, поэтому новые экземпляры инициализировались при помощи другого сообщения. Программист должен был удостовериться что каждый раз когда посылалось сообщение новый или новый: другое сообщение посылалось для правильной инициализации. Примеры такова вида инициализации были показаны в главе 4 для Малого словаря и Финансовой истории.

Система Смолток убрала ограничение на то что все классы используют одни и те же сообщения для создания экземпляров сделав каждый класс экземпляром своего собственного метакласса. Когда создаётся новый класс, для него автоматически создаётся новый метакласс. Метаклассы подобны другим классам т.к. они содержат методы используемые их экземплярами. Метаклассы отличаются от других классов потому что они не являются экземплярами метаклассов. Вместо этого все они являются экземплярами класса называемого Метакласс. Также метаклассы не имеют имени класса. Метаклассы доступны при помощи посылки сообщения класс их экземпляру. Например, метакласс Прямоугольника доступен при помощи предложения Прямоугольник класс.

Сообщения метакласса обычно поддерживают создание и инициализацию экземплров, и инициализации переменных класса.

Инициализация экземпляровПравить

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

Время текущее.
Дата сегодня.

Эти сообщения не понятны для Точки, класса чьи экземпляры представляют двумерную точку. Точка создаёт новые экземпляры в ответ на сообщения с селектором икс:игрек: и двумя аргументами определяющие координаты. В свою очередь это сообщение не понятно для Времени и Даты.

Точка икс: 100 игрек: 150.

Класс Прямоугольник понимает несколько сообщений которые создают экземпляры. Сообщение с селектором начало:угол: принимает Точки представляющие верхний левый и нижний правый углы в качестве аргументов.

Прямоугольник
   начало: (Точка икс: 50 игрек: 50)
   угол: (Точка икс: 250 игрек: 300).

Сообщение с селектором начало:размеры: получает в качестве аргументов верхний левый угол и Точку представляющую ширину и высоту. Тот же прямоугольник может быть создан следующим предложением.

Прямоугольник
   начало: (Точка икс: 50 игрек: 50)
   размеры: (Точка икс: 200 игрек: 250).

В системе Смолток Класс это абстрактный суперкласс для всех метаклассов. Класс описывает общие свойства классов. Каждый метакласс добавляет поведение особенное для данного экземпляра. Метаклассы могут добавлять новые сообщения создания экземпляров как это делают Дата, Время, Точка и Прямоугольник, или они могут переопределять сообщения новый и новый: для реализации некоторой инициализации по умолчанию.

Организация классов и экземпляров системы, как было описано выше, представлена на рисунке 5.2.

5.2.jpg

Рисунок 5.2

На этом рисунке мы видим классы Объект, Метакласс, Класс и метаклассы для каждого из них. Каждый кружок в прямоугольнике Метакласс обозначает метакласс. Каждый кружок в прямоугольнике Класс обозначает подкласс Класса. Есть один прямоугольник для каждого кружка в прямоугольнике Метакласс. Каждый из этих прямоугольников содержит кружки обозначающие его экземпляры; эти экземпляры ссылаются на Объект или один из подкласс Объекта, но не на метаклассы.

Пример метаклассаПравить

Т.к. есть соответствие один к одному между классом и его метаклассом, то их описания представляются вместе. Описание реализации включает часть называемую "методы класса" которая показывает методы добавленные метаклассом. Протокол для метакласса всегда находится при просмотре методов класса описания реализации его единственного экземпляра. Таким образом, сообщения посланные классу (методы класса) и сообщения посланные экземпляру класса (методы экземпляра) перечисляются вместе как части полного описания реализации.

Следующая новая версия описания реализации Финансовой истории включает методы класса.

имя класса Финансовая история
имена переменных экземпляра количество наличных приход расход
методы класса
создание экземпляра
инициализировать баланс: количество
   супер новый инициализировать баланс: количество.
методы экземпляра
запись транзакций
получить: количество из: источник
   приход от: источник пом: (сам общее поступление из: источник) + количество.
   количество наличныхколичество наличных + количество.

потратить: количество на: причина
   расход от: причина пом: (сам общие траты на: причина) + количество.
   количество наличныхколичество наличных - количество.

справки
количество наличных
   количество наличных.

общее поступление из: источник
   (приход содержит ключ: источник)
      истина: [ приход от: источник. ]
      ложь: [ 0. ].


общие траты на: причина
   (расход содержит ключ: причина)
      истина: [ расход от: причина. ]
      ложь: [ 0. ].

инициализация
инициализировать баланс: количество
   количество наличныхколичество.
   приходСловарь новый.
   расходСловарь новый.

Данный пример показывает как метакласс создаёт инициализированные экземпляры. Методы создания экземпляров не имеют прямого доступа к переменным экземпляра нового экземпляра (количество наличных, приход и расход). Это происходит из за того что методы создания экземпляра это не часть экземпляра класса, а часть класса класс. Поэтому методы создания экземпляров сначала создают неинициализированный экземпляр и затем посылают инициализирующее сообщение, инициализирвоать баланс:, новому экземпляру. Метод для этого сообщения находится в части методов экземпляра Финансовой истории; он может присваивать соответствующие значения переменным экземпляра. Обычно это сообщение посылается один раз и только методами класса.

Наследование метаклассовПравить

Подобно другим классам, метаклассы наследуют от суперклассов. Простейший способ организовать наследование метаклассов это сделать каждый из них подклассом Класса. Данная организация показана на рисунке 5.2. Класс описывает общие свойства классов. Каждый метакласс добавляет поведение особенное для своего экземпляра. Метаклассы могут добавлять новые сообщения создания экземпляров или могут переопределять сообщения новый и новый: для выполнения некоторой инициализации по умолчанию.

Когда метакласс добавляется к системе Смолток, происходит ещё одно действие в организации классов. Ирархия подклассов метакласса создаётся параллельно ирархии подклассов класса который является экземпляром метакласса. Т.е. если Налоговая история это подкласс Финансовой истории, то метакласс Налоговой истории должен стать подклассом метакласса Финансовой истории. Метакласс всегда имеет только один экземпляр.

Абстрактный класс Описание класса предоставляет описание классов и их экземпляров. Класс и Метакласс это подклассы Описания класса. Т.к. последовательно наследования всех объектов заканчивается Объектом и Объект не имеет суперкласса, то суперкласса метакласса Объекта это Класс. От Класса метаклассы наследуют сообщения которые предоставляют протокол для создания экземпляров (Рисунок 5.3.).

5.3.jpg

Рисунок 5.3

Последовательно суперклассов от Класса доходит в конечном счёте до Объекта. Заметьте что ирархия прямоугольников с именем класс Объекта подобна ирархии прямоугольнков с именем Объект; это подобие иллюстрирует параллельность наследования. Полное описание данной части системы, влючающие взаимоотношения между Метаклассом и это метаклассами представлено в главе 16.

В качестве примера наследования метаклассов рассмотрим реализацию инициализировать баланс: в классе Финансовой истории.

инициализировать баланс: количество
   супер новый инициализировать баланс: количество.

Этот метод создаёт экземпляр выполняя предложение супер новый; оно использует метод новый находящийся в методах класса суперкласса, не в методах класса находящихся в данном классе. Заметем он посылает новому экземпляру сообщение инициализировать баланс: с начальным количеством денег в виде аргумента.

Если мы выполним предложение

Финансовая история инициализировать баланс: 350.

поиск метода для отвена на инициализировать баланс: начнётся в классе Финансовой истории, т.е. в методах класса Финансовой истории. Метод с таким селектором находится здесь. Метод содержит два сообщения:

  1. Посылка суперу сообщения новый.
  2. Посылка результату первого пункта сообщения инициализировать баланс:.

Поиск метода новый начинается в суперклассе класса Финансовой истории, в данном случае, в классе Объекта. Метод здесь не находится, поэтому поиск продолжается в следующем суперклассе содержащесмся в цепи наследования т.е. в Классе. Сообщение находится в Классе, и оно выполняется используя примитивный метод. Реузльтат это неинициализированный экземпляр Финансовой истории. Затем этому экземпляру посылается сообщение инициализировать баланс:. Поиск метода для ответа начинается в классе экземпляра, т.е. в Финансовой истории (в методах экземпляра). Метода находится и при выполнении присваивает значение каждой переменной экземпляра.

Инициализация переменных классаПравить

Главный способ использования сообщений классу после создания экземпляров это инициализация переменных класса. Реализация описаний переменных даёт им только имена, но не значения. Когда класс создаётся, то создаются именованные переменные класса, но они все имеют значение пусто. Обычно метакласс определяет метод который инициализирует переменные класса. По соглашению, метод инициализации переменных класса обычно связан с унарным сообщением инициализировать в категории инициализация класса.

Переменные класса доступны и классу и его метаклассу. Присваивание значения переменной класса может быть выполнено в методе метакласса, в отличии от непрямого способа при помощи сообщения для переменных экземпляра.

Ниже показан пример Налоговой истории, в этот раз с переменными класса который нужно инициализировать. Налоговая история это подкласс Финансовой истории. Он определяет одну переменную класса, Минимальный налог.

имя класса Налоговая история
суперкласс Финансовая история
имена переменных экземпляра расходы на налоги
имена переменных класса Минимальный налог
методы класса
создание экземпляра
новая история |
   новая историясупер инициализировать баланс: количество.
   новая история инициализировать налоги.
   новая история.

новый
   | новая история |
   новая историясупер инициализировать баланс: 0.
   новая история инициализировать налоги.
   новая история.

инициализация класса
инициализировать
   Минимальный налог2300.
методы экземпляра
запись транзакций
потратить на налоги: количество на: причина
   сам потратить: количество на: причина.
   расходы на налогирасходы на налоги + количество.

потратить: количество на: причина вычесть: размер налога
   сам потратить: количество на: причина.
   расходы на налогирасходы на налоги + размер налога.

справки
детализированный
   расходы на налоги >= Минимальный налог.

всего налогов
   расходы на налоги.

собственные
инициализировать налоги
   расходы на налоги0.

Эта версия Налоговой истории добавляет пять методов экземпляра, один из которых это детализированный. Ответом на которое является истина или ложь в зависимости от того накопилось ли достаточно налогов чтобы детально их отражать в отчёте. Налоговое законодательство определяет минимальное количество налогов в размере 2300, поэтому если общее количество налогов меньше этой суммы, то следует использовать standard deduction. На константу 2300 ссылается переменная класса Минимальный налог. Чтобы посылка собщения детализированный экземпляру Налоговой истории прошла успешно, переменная класса Минимальный налог должна иметь численное значение. Это делается при помощи посылки сообщения инициализировать классу перед созданием экземпляров.

Налоговая история инициализировать.

Это сообщение посылается только один раз, после того как сообщение класса инициализировать будет определено. Переменная разделяется всеми экземплярами класса. В соответствии с приведённый описанием класса новый экземпляр Ноалоговой истории может быть создан при помощи сообщения классу инициализировать баланс: или новый. Предположим мы выполняем предложение

Налоговая история инициализировать баланс: 100.

Определение какие методы будут использоваться при выполнении предложения зависит от классов/суперклассов в последовательности наследования Налоговой истории. Метод инициализировать баланс: находится в методах класса Налоговой истории.

инициализировать баланс: количество
   | новая история |
   новая историясупер инициализировать баланс: количество.
   новая история инициализировать налоги.
   новая история.

Этот метод объявляет временную переменную новая история. Первое предложение метода это присваивание этой временной переменной.

новая историясупер инициализировать баланс: количество.

Псевдо переменная супер ссылается на получателя. Получатель это класс Налоговая история, его класс это метакласс. Суперкласс метакласса это метакласс Финансовой истории. Здесь мы будем искать метод который будет выполнять сообщение. Метод инициализировать баланс:

инициализировать баланс: количество
   супер новый инициализировать баланс: количество.

Мы уже рассматривали выполнение этого метода. Ответ на сообщение новый находится в Классе. Новый экземпляр получателя, Налоговой истории, создаётся и ему посылается сообщение инициализировать баланс:. Поиск метода инициализировать баланс: начинается в классе нового экземпляра, т.е. в Налоговой истории. Там он не находится. Поиск продолжается в суперклассе Налоговой истории. Он находится и выполняется. Переменным экземпляра описанным в Финансовой истории присваиваются значения. Затем значение первого предложения метода класса для селектора инициализировать баланс: в Налоговой истории частично инициализирует новый экземпляр. Этот новый экземпляр присваивается временной переменной новая история.

Затем новой истории посылается сообщение инициализировать налоги. Поиск начинается в классе получателя, новой истории; класс это Налоговая история. Метод находится. Он присваивает значение четвёртой переменной экземпляра значение 0.

Третье предложение сообщения создания экземпляра это возвращение нового экземпляра.

Далее представлен альтернативный способ реализации класса налоговая история. В этом альтернативном описании, методы создания экземпляра не переопределяются. Вместо этого сообщение инициализировать баланс: переопределено чтобы иметь доступ к дополнительным переменным экземпляра.

имя класса Налоговая история
суперкласс Финансовая история
имена переменных экземпляра расходы на налоги
имена переменных класса Минимальный налог
методы класса
инициализация класса
инициализировать
   Минимальный налог2300.
методы экземпляра
запись транзакций
потратить на налоги: количество на: причина
   сам потратить: количество на: причина.
   расходы на налогирасходы на налоги + количество.

потратить: количество на: причина вычесть: размер налога
   сам потратить: количество на: причина.
   расходы на налогирасходы на налоги + размер налога.

справки
детализированный
   расходы на налоги >= Минимальный налог.

всего налогов
   расходы на налоги.

собственные
инициализировать баланс: количество
   супер инициализировать баланс: количество.
   расходы на налоги0.

Используя это альтернативное описание для Налоговой истории, выполнение сообщения инициализировать баланс: в предложении

Налоговая история инициализировать баланс: 350.

вызывает поиск метода в классе Налоговой истории. Там он не находится. Поиск продолжается в суперклассе, в классе Налоговой истории. Здесь он находится. Выполнение метода содержит следующее предложение

супер новый инициализировать баланс: количество.

Метод для сообщения новый находится в Классе. Поиск метода инициализировать баланс: начинается в классе нового экземпляра, в Налоговой истории. Метод для инициализировать баланс: находится в Налоговой истории. Ответ на инициализировать балансе: в Налоговой истории это посылка того же сообщения суперу, поэтому поиск метода начинается в Налоговой истории. Метод находится и трё переменным экземпляра присваивается значение. Второе предложение метода инициализировать баланс: в Налоговой истории присваивает значение 0 четвёртой переменной. Результат изначального сообщения это полностью инициализированный экземпляр Налоговой истории.

Краткое изложение поиска методаПравить

Определение действий которые происходят при посылки сообщения включает в себя поиск метода в ирархии классов получателя. Поиск начинается с класса получателя и следует по цепи наследования. Если метод не находится после поска в последнем суперклассе, Объекте, то выдаётся сообщение об ошибке. Если получатель это класс, то его класс это суперкласс. Сообщения на которые класс может отвечать приводятся в описании реализации в разделе "методы класса". Если получатель это не класс, то сообщения на которые он может отвечать приводятся в описании реализации в части "методы экземпляра".

Псевдо переменная сам ссылается на получателя сообщения для которого выполняется метод. Поиск метода для сообщения себе начинается в классе себя. Псевдо переменная супер также ссылается на получателя сообщения. Поиск метода для сообщения посланного суперу начинается в суперклассе класса в котором находится выполняемый метод.

На этом описание языка Смолток заканчивается. Для использования системы программист должен иметь знания об основных классах системы. Вторая часть даёт детальное описание протокола сообщений для каждого класса системы и приводит примеры, часто показывая описание реализации классов системы. Третья часть вводит пример программы обозримого размера. Перед тем как перейти к классам системы, читатель может перепрыгнуть к третьей части чтобы почувствовать как пишутся большие программы.

Сводка терминологииПравить

метакласс - класс класса.

Класс - абстрактный суперкласс для всех классов отличных от метаклассов.

Метакласс - класс чьи экземпляры это классы классов.

Обнаружено использование расширения AdBlock.


Викия — это свободный ресурс, который существует и развивается за счёт рекламы. Для блокирующих рекламу пользователей мы предоставляем модифицированную версию сайта.

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

Также на Фэндоме

Случайная вики