Evgenii Legotckoi
Маусым 27, 2016, 12:43 Т.Қ.

Пайдаланушы нұсқаулығы №15 - Ruby - Access Control

Недавно, мы говорили, что Ruby не имеет функций, только методы. Однако имеется более, чем один вид методов. В этой главе мы ознакомимся с контролем доступа.

Рассмотрим, что происходит, когда мы определяем метод на верхнем уровне, не внутри определения класса. Мы можем подумать, что этот метод будет аналогичен функции в более традиционном языке, таком как C.

  1. ruby> def square(n)
  2. | n * n
  3. | end
  4. nil
  5. ruby> square(5)
  6. 25

Наш новый метод, как кажется, не принадлежит никакому класса, но фактически руби даёт ему класс Object , который является суперклассом для каждого другого класса. В результате, любой объект сможет использовать этот метод. Это справедливо , но имеется небольшая загвоздка: это приватный метод каждого класса. Мы обсудим что это означает ниже, но одним из следствий этого является то, что он может быть вызван только в стиле функции, как здесь:

  1. ruby> class Foo
  2. | def fourth_power_of(x)
  3. | square(x) * square(x)
  4. | end
  5. | end
  6. nil
  7. ruby> Foo.new.fourth_power_of 10
  8. 10000

Нам не позволяется выполнять данный метод как метод объекта:

  1. ruby> "fish".square(5)
  2. ERR: (eval):1: private method `square' called for "fish":String

Это сохраняет Объектно-ориентированную природу Ruby более чистой (функции всё ещё являются методами объекта, но приёмником неявно является self ) в то время как функции могут быть написаны как в традиционном языке.

Традиционным подходом в объектно-ориентированном программировании, о котором мы намекали в недавних главах, имеется разделение на спецификацию и имплементацию, или какие задачи объекта предполагается выполнять и как они на самом деле выполняются. Внутренняя работа объекта должна сохраняться, как правило, скрытой от пользователей. Они должны заботиться только о том, какие данные выходят и выходят в объект, и верить тому, что объекта знает, что делать с данными внутри себя. Таким образом, часто бывает полезным для классов иметь методы, которые не видны внешнему миру, но которые используются в внутри (и могут быть улучшены программистом, когда он пожелает, без изменения видения пользователями объекта снаружи. В обычном примере, что следует далее, думаем об engine как о невидимом внутреннем работнике класса.

  1. ruby> class Test
  2. | def times_two(a)
  3. | print a," times two is ",engine(a),"\n"
  4. | end
  5. | def engine(b)
  6. | b*2
  7. | end
  8. | private:engine # this hides engine from users
  9. | end
  10. Test
  11. ruby> test = Test.new
  12. #<Test:0x4017181c>
  13. ruby> test.engine(6)
  14. ERR: (eval):1: private method `engine' called for #<Test:0x4017181c>
  15. ruby> test.times_two(6)
  16. 6 times two is 12.
  17. nil

Мы могли бы ожидать выполнения test.engine(6) для возврата значения 12, но вместо этого мы видим, что engine недоступен, когда пользователь применяет его к экземпляру класса Test . Только другим методам класса Test , таким как times_two , позволяется использовать engien . Нам требуется использовать публичный интерфейс, который содержится в методе times_two. Программист, который отвечает за этот класс, может изменить engine (здесь, возможно изменение с b 2 на b+b для улучшения производительности) не затрагивая того, как пользователь взаимодействует с объектами Test.* Этот пример, конечно, очень простой, чтобы быть полезным; преимущества контроля доступа становятся более ясны только тогда, когда мы начинаем создавать более сложные и интересные классы.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз