@@count += 1
@myvar = 10
end
def MyClass.getcount # метод класса
@@count # переменная класса
end
def getcount # экземпляр возвращает переменную класса!
@@count # переменная класса
end
def getmyvar # метод экземпляра
@myvar # переменная экземпляра
end
def setmyvar(val) # метод экземпляра устанавливает @myvar
@myvar = val
end
def myvar=(val) # другой способ установить @myvar
@myvar = val
end
end
foo = MyClass.new # @myvar равно 10
foo.setmyvar 20 # @myvar равно 20
foo.myvar =30 # @myvar равно 30
Здесь мы видим, что getmyvarвозвращает значение переменной @myvar, а setmyvarустанавливает его. (Многие программисты говорят о методах чтения и установки). Все это работает, но не является характерным способом действий в Ruby. Метод myvar=похож на перегруженный оператор присваивания (хотя, строго говоря, таковым не является); это более удачная альтернатива setmyvar, но есть способ еще лучше.
Класс Moduleсодержит методы attr, attr_accessor, attr_readerи attr_writer. Ими можно пользоваться (передавая символы в качестве параметров) для автоматизации управления доступом к данным экземпляра. Например, все три метода getmyvar, setmyvarи myvar=можно заменить одной строкой в определении класса:
attr_accessor :myvar
При этом создается метод myvar, который возвращает значение @myvar, и метод myvar=, который позволяет изменить значение той же переменной. Методы attr_readerи attr_writer создают соответственно версии методов доступа к атрибуту для чтения и для изменения.
Внутри методов экземпляра, определенных в классе, можно при необходимости пользоваться переменной self. Это просто ссылка на объект, от имени которого вызван метод экземпляра.
Для управления видимостью методов класса можно пользоваться модификаторами private, protectedи public. (Переменные экземпляра всегда закрыты, обращаться к ним извне класса можно только с помощью методов доступа.) Каждый модификатор принимает в качестве параметра символ, например : foo, а если он опущен, то действие модификатора распространяется на все последующие определения в классе. Пример:
class MyClass
def method1
# ...
end
def method2
# ...
end
def method3
# ...
end
private :method1
public
:method2
protected :method3
private
def my_method
# ...
end
def another_method
# ...
end
end
В этом классе метод method1закрытый, method2открытый, a method3защищенный. Поскольку далее вызывается метод privateбез параметров, то методы my_methodи another_methodбудут закрытыми.
Уровень доступа publicне нуждается в объяснениях, он не налагает никаких ограничений ни на доступ к методу, ни на его видимость. Уровень privateозначает, что метод доступен исключительно внутри класса или его подклассов и может вызываться только в «функциональной форме» от имени self, причем вызывающий объект может указываться явно или подразумеваться неявно. Уровень protectedозначает, что метод вызывается только внутри класса, но, в отличие от закрытого метода, не обязательно от имени self.
По умолчанию все определенные в классе методы открыты. Исключение составляет лишь initialize. Методы, определенные на верхнем уровне программы, тоже по умолчанию открыты. Если они объявлены закрытыми, то могут вызываться только в функциональной форме (как, например, методы, определенные в классе Object).
Классы в Ruby сами являются объектами — экземплярами метакласса Class. Классы в этом языке всегда конкретны, абстрактных классов не существует. Однако теоретически можно реализовать и абстрактные классы, если вам это для чего-то понадобится.
Класс Objectявляется корнем иерархии. Он предоставляет все методы, определенные во встроенном модуле Kernel.
Чтобы создать класс, наследующий другому классу, нужно поступить следующим образом:
class MyClass < OtherClass
# ...
end
Помимо использования встроенных методов, вполне естественно определить и собственные либо переопределить унаследованные. Если определяемый метод имеет то же имя, что и существующий, то старый метод замещается. Если новый метод должен обратиться к замещенному им «родительскому» методу (так бывает часто), можно воспользоваться ключевым словом super.
Читать дальше
Конец ознакомительного отрывка
Купить книгу