Шрифт:
В языке Ruby есть все элементы, которые принято ассоциировать с объектно-ориентированными языками: объекты с инкапсуляцией и сокрытием данных, методы с полиморфизмом и переопределением, классы с иерархией и наследованием. Но Ruby идет дальше, добавляя ограниченные возможности создания метаклассов, синглетные методы, модули и классы-примеси.
Похожие идеи, только под иными именами, встречаются и в других объектно-ориентированных языках, но одно и то же название может скрывать тонкие различия. В этом разделе мы уточним, что в Ruby понимается под каждым из элементов ООП.
1.3.1. Объекты
В Ruby все числа, строки, массивы, регулярные выражения и многие другие сущности фактически являются объектами. Работа программы состоит в вызове методов разных объектов:
В Ruby каждый объект представляет собой экземпляр какого-то класса. Класс содержит реализацию методов:
Помимо инкапсуляции собственных атрибутов и операций объект в Ruby имеет уникальный идентификатор:
Этот идентификатор объекта обычно не представляет интереса для программиста.
1.3.2. Встроенные классы
Свыше 30 классов уже встроено в Ruby. Как и во многих других объектно-ориентированных языках, в нем не допускается множественное наследование, но это еще не означает, что язык стал менее выразительным. Современные языки часто построены согласно модели одиночного наследования. Ruby поддерживает модули и классы-примеси, которые мы обсудим в следующей главе. Также реализованы идентификаторы объектов, что позволяет строить устойчивые, распределенные и перемещаемые объекты.
Для создания объекта существующего класса обычно используется метод
Однако не всегда его обязательно вызывать явно. В частности, при создании объекта String можно и не упоминать этот метод:
Ссылки на объекты хранятся в переменных. Выше уже отмечалось, что сами переменные не имеют типа и не являются объектами — они лишь ссылаются на объекты.
Из этого правила есть исключение: небольшие неизменяемые объекты некоторых встроенных классов, например
При присваивании переменных ссылки на объекты обобществляются.
После выполнения присваивания
Если объект изменяемый, то модификация, примененная к одной переменной, отражается и на другой:
Однако новое присваивание любой из этих переменных не влияет на другую:
Изменяемый объект можно сделать неизменяемым, вызвав метод
Символ в Ruby ссылается на переменную по имени, а не по ссылке. Во многих случаях он может вообще не ссылаться на идентификатор, а вести себя как некая разновидность неизменяемой строки. Символ можно преобразовать в строку с помощью метода
Продемонстрированный выше фокус с «перечислением» был более осмыслен на ранних этапах развития Ruby, когда еще не было класса