Smalltalk в примерах/Основы: различия между версиями

Содержимое удалено Содержимое добавлено
→‎Инкапсуляция: Выкинул неработающий Latex код для вставки картинки
Выкинул ссылки на дохлые рисунки: надо - откатите на три правки назад
 
Строка 19:
== Инкапсуляция ==
 
Когда ты посылаешь сообщение <tt>покупка: количествоАкций цена: цена</tt> конкретному объекту акция, он обновляет переменные экземпляра ''цена, последняяСделка'' и ''объёмСделок''. Не существует ''другого'' пути для изменения этих переменных. Ни один другой объект не может прочитать или изменить данные объекта XYZ. Это можно сделать только посылая объекту <tt>XYZ</tt> сообщение. Некоторые сообщения обновляют данные объекта акция, и некоторые сообщения возвращают значения. Но ни один объект не может получить доступ к данным напрямую. Данные ''инкапсулированы'' в объекте. Рисунок~\ref{incapsulxcyx} показывает представление данной инкапсуляции.
 
Тот факт что данные инкапсулированы означает что мы можем изменить способ их хранения. Так долго как мы сохраняем общедоступный интерфейс который мы определили — сообщения на которые объект отвечает, мы можем делать всё что захотим внутри объекта. В один день мы можем решить хранить цену в долларах и центах, в следующий день в центах, в следующий день в восьмёрках долларов, и т. д. Так долго как мы также меняем способ которым метод <tt>цена</tt> манипулирует данными до их возвращения, мы поддерживаем общедоступный интерфейс несмотря на то что объект внутренне изменяется.
Строка 31:
Мы не должны писать методы <tt>добавить:</tt> и <tt>первый</tt> дважды, один раз для каждого объекта. Вместо этого мы нуждаемся в механизме для написания кода однажды и использования его для обеих УпорядоченныхСовокупностей. Вот откуда появляется концепция <i>класса</i>. Класс это просто проект или шаблон для того как объект должен выглядеть: какие переменные он содержит и какие сообщения он понимает. Мы определили класс УпорядоченнойСовокупности в котором мы написали код для сообщений <tt>добавить:</tt> и для <tt>первый</tt>. Таким образом вы можете рассматривать класс УпорядоченнаяСовокупность как хранилище для кода который выполняется когда вы посылаете сообщение. Написав код однажды все УпорядоченныеСовокупности (в нашем случае две) могут выполнять его.
 
Код хранится в <i>методах</i>. Когда объект получает сообщение он выполняет <i>метод</i> с тем же именем. Таким образом мы написали методы и они хранятся в классе. Рисунок~\ref{hraniliwe} показывает пример класса Служащий, показано как класс работает в качестве шаблона и в качестве хранилища кода.
 
===Класс как фабрика===
Строка 76:
и рассмотрим совокупность, строки будут в следующем порядке 'abc', 'def', 'xyz', в правильной отсортированной последовательности для строк. Таким образом, в СортированойСовокупности мы не должны наследовать код суперкласса для <tt>добавить:</tt>. Вместо этого мы пишем свой собственный код для метода <tt>добавить:</tt> и подменяем код определённый в УпорядоченнойСовокупности.
 
Второй случай когда мы нуждаемся в различном поведении это добавление поведения - делать что-либо что суперкласс не может делать. Например, мы должны определить алгоритм сортировки который должен использоваться экземплярами СортированойСовокупности. Мы добавляем поведение очень легко, просто написав новый метод для СортированойСовокупности. Например в случае сортирующего алгоритма мы пишем метод <tt>сортирующийБлок:</tt> который запоминает новый алгоритм для будущего добавления и также для пересортировки совокупности в соответствии с новым алгоритмом. Рисунок~\ref{nasledovanie} показывает пример наследования, переписывания, и добавления методов.
 
\begin{figure}[!htb]
\begin{center}
\includegraphics{inheritance.eps}
\end{center}
\caption{Наследование}
\label{nasledovanie}
\end{figure}
 
==Полиморфизм==
Строка 103 ⟶ 96 :
Рассмотрим другой пример, мы имеем объект Офис который видит объекты Работник приходящих на работу. Один подход для объекта Офис спросить объект работник какого типа он работник. Если это объект Программист, объект Офис должен сказать ему начать программировать (<tt>программист начниПрограммировать</tt>). Если это служащий, объект Офис должен сказать ему отвечай на телефонные звонки (<tt>служащий отвечайНаТелЗвонки</tt>). Если это мэнеджер, объект Офис должен сказать ему работай с бумагами (<tt>мэнеджер работайСБумагами</tt>).
 
Такой подход неудобен из за того что надо иметь код единственная задача которого проверять какого типа объект Работник просто спрашивая его, и надо изменять данный код когда добавляется новый тип работника. Лучший подход для объекта Офис не интересоваться типом работника, а просто говорить ему делать работу(<tt>работник принимайсяЗаРаботу</tt>). Если объект Программист получает это сообщение, он должен начать программировать; если объект Служащий получает это сообщение, он должен начать отвечать на телефонные звонки; если объект Мэнеджер получает это сообщение, он должен начать работать с бумагами. Сейчас когда вы добавите новый тип работника, вы просто должны быть уверены что он отвечает на сообщение <tt>принимайсяЗаРаботу</tt> и делает соответствующую работу. Мы передали ответственность тем к кому она относится. Рисунок~\ref{polimorfizm} показывает пример полиморфизма.
 
\begin{figure}[!htb]
\begin{center}
\includegraphics{polymorphism.eps}
\end{center}
\caption{Полиморфизм}
\label{polimorfizm}
\end{figure}
 
Возможность понимания одинаковых сообщений различными способами различными объектами означает что мы можем <i>принимать решения</i> и <i>командовать</i>. Это фундаментальное различие между процедурным мышлением и объектно-ориентированным мышлением. Интерпретация одного и того же сообщения по разному называется <i>полиморфизм</i>. Это работает потому что есть разница между <i>сообщением</i> и <i>функцией</i>. Когда сообщение посылается объекту, объект просматривает имя сообщения (<i>селектор</i> в терминологии Smalltalk) в списке сообщений на которые он отвечает. С селектором сообщения связан метод --- несколько строк кода которые должны быть выполнены. Таким образом, один селектор сообщения можэт быть связан с различным кодом для различных классов.
Строка 123 ⟶ 108 :
Класс УпорядоченнаяСовокупность существует как место для хранения кода который является общим для упомянутых классов. Общее поведение отделяется помещается в абстрактный суперкласс, который не может иметь экземпляров --- т.е. не должен создавать экземпляры себя. Например методы <tt>копироватьОт:до:</tt> и <tt>наличие---</tt>: оба написаны в РегулярнойСовокупности и наследуются её подклассами.
 
Таким образом, абстрактный суперкласс это класс который не имеет своих экземпляров, но который существует как хранилище для общего кода. Абстрактный суперкласс РегулярнаяСовокупность сам имеет абстрактный суперкласс, <i>Совокупность</i>. Совокупность это также суперкласс для <i>Множества</i> и <i>Мешка</i>, совокупностей для которых нет понятия порядка. Совокупность обеспечивает поведение которое является общим для всех совокупностей, такое как <tt>пустая?</tt>, <tt>собрать:</tt>, <tt>делать:</tt> и <tt>включает:</tt>. (Некоторые подклассы переопределяют эти методы для осуществления подходящего поведения. Однако, многие подклассы наследуют поведение напрямую.) Рисунок~\ref{ierarhix} показывает малую часть иерархии Совокупностей.
 
\begin{figure}[!htb]
\begin{center}
\includegraphics{hierarchy.eps}
\end{center}
\caption{Иерархия Совокупностей}
\label{ierarhix}
\end{figure}
 
==Резюме==