«Все в Ruby — это объект», — это единственное, что я постоянно слышу, изучая Ruby.

Классы

Классы — это, по сути, небольшие «фабрики», создающие объекты. Эти объекты имеют встроенные методы и атрибуты. IRB — это инструмент, используемый для выполнения выражений Ruby, считанных из стандартного ввода. Я собираюсь запустить IRB, набрать несколько строк и объяснить, что происходит.

1. "name"
2.=> "name"
3. "name".upcase
4. => "NAME"
5. "name".class
6. => String

Строка 1 создает строку «имя».

Строка 2 выводит строку «имя», которую я только что создал.

Строка 3 показывает, что «имя» имеет встроенные методы, которые могут каким-то образом воздействовать на этот объект. В данном случае .upcase — это метод, который делает строку «имя» заглавной.

Строка 4 выводит «NAME» после вызова метода .upcase для «name» и нажатия клавиши ввода.

Строка 5. Выполнение .class для фрагмента данных возвращает тип данных этого фрагмента данных.

Строка 6 возвращает тип данных «имя», в данном случае это «STRING».

Помимо типа данных, «STRING», который мы видели в строке 6, также является родительским классом, из которого получен этот экземпляр строки.

Создание класса и экземпляра этого класса

class Student
  #some code to describe a student
end

elton = Student.new
elton => #=> #<Student: 0x007fc52c3d9d10>

В Ruby для создания класса я сначала использую ключевое слово class, нажимаю пробел и определяю класс с заглавной буквы. Если я хочу создать класс, содержащий два слова, имя должно быть PascalCased. Наконец, я набираю «конец», чтобы закончить свой урок. Я создал класс под названием «Студент». Класс Student — это схемы, показывающие, как создавать отдельные объекты для учащихся. Эти объекты содержат всю информацию и поведение отдельного ученика.

Переменная elton указывает на новый экземпляр студента. В классе Student я вызываю метод .new, который создает экземпляр или создает новый экземпляр студент. Каждый конкретный учащийся называется экземпляром. Экземпляр – это единичное вхождение объекта, созданного из класса.

Я создам больше учеников:

Теперь у нас есть переменные elton, mark и roberto, указывающие на отдельные экземпляры класса Student.

Так что же такое #‹Student:0x00007f8a0697dc08›? Это Ruby Object Notation: способ, которым Ruby сообщает вам, что вы имеете дело с объектом. #‹Student:0x00007f8a0697dc08› — это идентификатор, и именно здесь объект находится в памяти. Три экземпляра Student, которые я создал, уникальны, несмотря на то, что они взяты из Student.

Методы экземпляра

Чтобы увидеть список методов, которые я могу вызывать для экземпляров своего класса, я могу вызвать метод #methods для одного из экземпляров:

Ух ты! Все эти встроенные методы стали доступны мне, когда я создал класс. Это не самая крутая часть всего этого. Самое крутое, что я могу создавать свои собственные. Так как же создать метод экземпляра для класса Student? Как я могу научить студентов поднимать руку? Я могу создать метод экземпляра, используяключевое словоdef внутри своего класса:

Когда я определил #raise_hand в классе Student, raise_hand становится #методом всех экземпляров Студент. Итак, теперь все студенческие экземпляры, которые я создаю, смогут поднять руку.

На чем мы стоим: я могу создавать классы, экземпляры этих классов, а внутри этих классов я могу создавать методы экземпляров, определяющие, что могут делать мои экземпляры.

Предоставление атрибутов класса

Как правило, когда я создаю класс, я хочу дать этому классу некоторые атрибуты. Я хочу, чтобы мой класс Студент имел атрибут имя и атрибут возраст. Чтобы добавить эти атрибуты в мой класс, я делаю:

class Student
  attr_accessor :name, :age
end

Здесь я говорю, что все экземпляры моего класса Student будут иметь атрибуты name и age. Метод attr_accessor используется, когда необходимы и attr_reader, и attr_writer. Как чтение, так и запись данных распространены в Ruby, поэтому attr_accesor является полезным ярлыком. Теперь, когда я добавил атрибуты в свой класс, я могу присвоить своим трем экземплярам Student имя и возраст. Я сделаю это для одного из моих студенческих экземпляров.

Теперь я могу создать столько учеников, сколько захочу, и дать каждому ученику имя и возраст. Однако на рисунке выше показан утомительный способ создания новых экземпляров нашего класса Student. Что делать, если я хочу создать 10 студентов? А 50? 100? Ух ты, много печатать, а в моем случае много опечаток.

Есть более простой способ.

Инициализировать

Более простой способ — использовать специальный встроенный метод инициализации. Я могу определить его в моем классе Student, и он определяется так же, как мой метод экземпляра raise_hand выше, за исключением использования ключевого слова initialize. Метод #initialize — это метод, который вызывается автоматически всякий раз, когда используется .new. Если я хочу, чтобы каждый экземпляр моего класса Student создавался с определенными данными, мне нужно определить метод #initialize:

Теперь, когда я хочу создать ученика, я могу указать ему имя и возраст в одной строке вместо того, чтобы вводить «student1.name= «Elton»» и в отдельной строке «student1.age=10». Это помогает уменьшить количество строк, которые мне нужно вводить каждый раз, когда я хочу создать новый экземпляр учащегося. Удивительный.

Когда я говорю «@name», я имею в виду атрибут имени в моем объекте, который я определил в строке 2. Я устанавливаю имя экземпляра моего класса Student равным имени, которое получил прошел в очереди 9. Как и в случае с возрастом. "@name" – это переменная экземпляра. Переменные экземпляра описывают атрибуты экземпляра. Теперь я могу вызывать его по всему классу без необходимости передавать его другому методу в качестве аргумента, как если бы вы делали это с локальной переменной.

Себя

Я буду продолжать пополнять свой класс Student. Допустим, я хочу создать метод внутри своего класса Student, который помещает приветствие для одного из моих объектов ученика. Это будет выглядеть примерно так:

Ключевое слово self относится к имени или возрасту конкретного объекта, вызывающего метод приветствия. В этом случае объект student1 вызвал метод приветствия, поэтому он вернет имя и возраст для этого конкретного объекта. Другими словами, ключевое слово self относится к экземпляру, для которого вызывается метод #greeting. Так круто.

Переменные класса и методы класса

Помимо возможности создавать переменные экземпляра и методы экземпляра в Ruby, я также могу создавать переменные класса и методы класса. Переменные экземпляра содержат информацию об экземпляре и могут быть легко идентифицированы, поскольку перед ними стоит один знак «@». В моем примере выше "@name" и "@age" являются переменными экземпляра. Переменные экземпляра доступны для всех методов экземпляра в классе. Переменные класса хранят значения, относящиеся к классу, а не к конкретному экземпляру класса, и их также легко идентифицировать, поскольку перед ними стоят два знака «@». Они доступны всему классу. Допустим, я хочу узнать у своего класса Student, сколько учеников он создал. Я должен начать с определения переменной класса внутри моего класса Student:

Я сделал это в строке 3. Я создал переменную класса student_count. Чтобы иметь возможность подсчитывать всех моих учеников, мне нужно наращивать возможности. Я не предоставил своей программе возможность возвращать количество студентов. Далее мне нужно создать метод класса.

Методы класса используются для реализации поведения, связанного с классом, а не с экземпляром. Методы экземпляра используются для реализации поведения, связанного с экземпляром, а не со всем классом. Я собираюсь создать метод класса, чтобы показать синтаксис:

Чтобы создать метод класса, я использую ключевое слово def, за которым следует ключевое слово self и, наконец, .name_of_my_class_method. Я относится ко всему классу, а не к экземпляру класса. Затем я добавил метод класса .count, который возвращает количество студентов.

Подводя итог, у меня есть класс Student, и внутри этого класса у меня есть переменная класса student_count, которую я определил в строке 3, и метод класса .count (определено в строке 5), который возвращает количество моих учеников.

Собираем все вместе

Теперь, когда я знаю, как создавать классы, экземпляры этих классов, переменные экземпляра, переменные класса, методы экземпляра и методы класса, теперь я смогу добавить больше функциональности в свою программу.

Допустим, я хочу отслеживать, сколько учеников я создаю. Для этого мне понадобится счетчик, начинающийся с 0. У меня нет учеников, пока я не начну их создавать. Для этого мне нужно будет создать переменную класса и установить ее равной 0.

Я сделал это в строке 3. Но подождите, я создал новый экземпляр студента, но когда я ввожу «Student.count», я все равно получаю 0.

Чтобы счетчик поднимался каждый раз, когда я создаю или инициализирую экземпляр класса Student, мне нужно добавить его в мой метод #initialize:

Вуаля.