Подпрограммы и модули решают важную задачу отделения интерфейса, обеспечивающего их полное и правильное использование, от реализации — внутреннего устройства модуля или подпрограммы. При этом, особенности реализации, такие как локальные переменные, конкретный алгоритм, и т.д.— оказываются скрытыми. Скрытие реализации имеет место и для встроенных типов данных. Представление чисел типа real для большинства программистов является загадкой. Но возможно вы знаете, что в Borland Pascal строки занимают 256 байт, причем нулевой байт содержит длину строки. Аналогично устроены и строки в 16–ти разрядной версии Delphi. С чьей–то легкой руки это свойство строк стало широко известно, но оно является реализацией.
Хороший стиль программирования не допускает использования особенностей реализации. Если в некоторых случаях вы писали Ord(s[0]) вместо Lenght(s), вы это правило нарушали. Расплатой послужит то, что в Delphi ваши программы перестанут работать — представление строк изменилось. Обратите внимание, что разработчики новой версии не несут никакой ответственности за это, они вам дали функцию Length. Ошибку делали вы.
Нельзя ли предупредить подобные ошибки в типах создаваемых программистом? Оказывается в ООП это не только можно, но и нужно делать. Разработчик класса должен представить пользователю все необходимые средства для работы с объектами (интерфейс), но скрыть конкретные детали устройства класса (реализацию).
Так для нашего класса TCircle естественно потребовать, чтобы радиус окружности был больше или равен 0. Этого нельзя гарантировать, скажем, для записи. Ведь нехороший программист всегда может сделать что–нибудь вроде c1.Fr := -1. В действительности, представление радиуса числом типа real является особенностью реализации , поэтому прямой доступ к полю Fr следует закрыть.
Объявление класса разбивается на зоны с разной областью видимости: public (общая) и private (частная). Все, что объявлено в зоне public, может использоваться не только в методах класса, но и в любых других частях программы. Все, что объявлено в зоне private, может быть использовано только методами этого класса. Объявленные в private поля и методы не доступны даже классам–потомкам.
Если зона явно не указана, Pascal понимает ее как public. Т.е. наши классы имеют только зону public, и инструкция c1.Fr := -1 для TCircle допустима в любой части программы. Давайте усовершенствуем их определения:
Теперь обратиться непосредственно к полям класса вне методов TCircle невозможно. Подобная попытка приведет к ошибке в процессе компиляции. Единственный способ изменять поля в других частях программы — это вызывать методы SetX, SetY и SetR. А в SetR можно проверить значение параметра и не допустить запрещенной величины радиуса.
Обратите внимание на тот факт, что нам не пришлось переписывать методы, в частности, метод Distance использует закрытые поля Fx и Fy объекта, переданного как параметр. Это допустимо, ведь оба объекта принадлежат одному классу. Таким образом,
ограничение области видимости относится не к объекту, а к классу.
В Delphi существуют два других типа областей видимости. Мы коснемся только одного — protected. Все что указано в зоне protected доступно в методах классов–потомков. Кроме того, классы–потомки могут переносить такие объявления в область public.
Для обычных процедур и функций, определенных в других модулях, а так же для методов классов, не являющихся наследниками данного класса, компоненты из раздела protected не доступны. Таким образом, поля и методы объявленные в части protected, имеют область видимости, ограниченную потомками класса.
Возможность ограничения областей видимости составляет вторую часть понятия инкапсуляции. Язык позволяет скрывать несущественные особенности реализации класса. Скрывая поля, программист обязан предоставить методы для работы с ними, объединив их в одно понятие — класс.
Строгие правила скрытия внутреннего устройства классов из практических соображений несколько смягчены. Они действуют только вне модуля (unit), в котором описан класс. В пределах модуля, содержащего объявление класса, механизмы инкапсуляции в Delphi, выключены!
Это позволяет создавать тесные группы классов, которые “знают все друг о друге” и даже обычные процедуры, имеющие доступ к закрытым полям класса. С другой стороны, такое правило заставляет помещать законченные классы в законченные модули, дабы гарантировать их правильное использование.
Опубликовал Kest
May 29 2011 21:26:55 ·
0 Комментариев ·
6922 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.