Классы, методы и объекты
Как мы ранее говорили, класс - это шаблон нашего объекта. В нем мы описываем какие атрибуты могут быть у объекта и какие методы у него есть, с помощью которых мы можем взаимодействовать с объектом. Давайте посмотрим как создать наш класс:
Названия классов следует всегда записывать в формате CamelCase
(Каждое слово в названии пишется с заглавной буквы), например MagicBall
.
Ранее при создании объекта вы встречали такое слово как new
. Фактически, вызывая метод new
у класса вы вызываете его конструктор. В конструкторе вы можете определить сколько угодно аргументов как и у любого другого метода, но сами по себе аргументы никакого отношения к самому классу не имеют, это просто набор параметров, которые можно передать при создании объекта. Для того, чтобы аргументы стали частью объекта, его атрибутами, необходимо создать эти самые атрибуты и прировнять их к аргументам. атрибуты объекта создаются с помощью знака @
перед названием самого атрибута. Сделав это, ваш объект при создании уже будет иметь какое-то собственное состояние.
Объекты
Давайте посмотрим как нам теперь создать наш объект на основе этого класса:
Как мы видим при инспектировании данных объектов они имеют абсолютно отличающиеся данные внутри себя.
Методы
Хорошо, у нас есть класс, есть несколько экземпляров этого класса с отличающимися атрибутами. Но что мы можем с ним делать ? Все что душе угодно. Для начала давайте посмотрим как мы можем изменять состояние этих самых объектов
Для того, чтобы ваш код не превратился в кашу, создавайте новые классы в новых файлах, записанные в формате lower_case
. Например наш класс Person
, значит файл должен называться person.rb
, класс называется MagicBall
, значит файл называется magic_ball.rb
и тд. Как использовать код из одного файла внутри другого ? Воспользуйтесь ключевым словом require
или require_relative
. Подробнее про это будет сказано в доп. материале.
Переменные и методы класса
Помимо наших обычных переменных объекта, которые мы объявляем с помощью @
, существуют еще переменные класса, которые объявляются с помощью @@
. Отличие от переменных объекта в том, что значение переменной объекта у каждого свое, оно является состоянием нашего объекта, в то время как переменная класса принадлежит целому классу и доступ к ней есть у любого объекта этого класса. Каждые раз создавая новый объект вы создаете, по большому счету, новый объект с новыми переменными. Если у объекта 3 переменные, вы создали 2 объекта, то фактически создаются 6 переменных, так как класс это в каком-то роде еще одна структруа данных. В случае с переменной класса она создается один раз и может быть переиспользована сразу в нескольких объектах. 1 переменная класса, 5 объектов, кол-во созданных переменных класса не меняется.
Методы класса точно так же как и переменные не завязаны на объекте, а являются частью класса. Записать метод класса можно следующим образом:
Запись через self.method
или через class << self
зависит вашего стиля кода или вашей команды. Старайтесь придерживаться правила: если у вас один метод класса, то лучше записать его с помощью self.
, если у вас несколько таких методов, то лучше вынести их во внутрь class << self
, так как это позволяет нам поддерживать чистоту в и простоту в нашем коде.
Константы
Константы очень похожи по своей сути на переменные класса, но их концепция не завязана на ООП. Для объявления константы вам нужно записать ее как обычную переменную без @
, но полностью заглавными буквами в формате snake_case
. Константы можно определить и в обычном ruby файле без использования классов. Если в случае с переменными класса мы можем менять их значение без каких либо проблем, то в случае с константами при изменении значения мы увидим warning
сообщение: warning: already initialized constant CONSTANT_NAME
, при этом значение все равно поменяется.
К сожалению у нас нет возможности сделать константу неизменяемой, но у нас есть возможность сделать значение иммутабельным
Давайте посмотрим как это выглядит для класса:
Так же хорошей практикой является создавать отдельные классы для хранения однотипных констант
В главе про наследование мы еще раз поговорим про константы и переменные класса, почему их использование может навредить программе, но так или иначе данные конструкции языка все равно понадобятся для решения домашнего задания
self
В прошлым примерах вы уже сталкивались с ключевым словом self
, а теперь стоит разобрать что это такое. Мы привыкли уже создавать наши объекты, помоещать их в переменную6 а после передавать эту переменную куда-то еще (либо без переменной, сразу как значение передавать), но что если мы хотим получать доступ к объекту сразу изнутри этого самого объекта ? self
позволяет нам внутри нашего класса обращаться к будущему объекту, который будет создан на основе этого класса. Звучит сложно, но с примером будет полегче
Также, self
как мы рассматривали ранее, служит еще и для создания методов класса.
Задание animals
Внимание ! Это и последующие задания данного модуля с названием animals
необходимо выполнять в одной и той же директории в корне модуля - 3_oop/animals
Реализовать класс Cat у которого есть такие атрибуты как
name
(имя) иweight
(вес) (в граммах)Добавьте константы в которых будет указан
MIN_WEIGHT
(минимальный вес) равный 1000грамм иMAX_WEIGHT
(максимальный вес) равный 9000грамм.Создайте конструктор, который будет принимать имя в аргументах, а вес будет устанавливаться случайным образом между минимальным и максимальным весом.
Реализуйте следующие методы:
toilet
- кот ходит в туалет и теряет 1 грамм своего веса.voice
- кот издает голос 'Meow' в консоль и теряет 1 грамм своего веса.eat(food_grams)
- кот принимает пишу. В аргументах он получает кол-во еды в граммах и пополняет вес на кол-во употребеленной еды.drink(water_ml)
- кот пьет воду. В аргументах он получает кол-во воды в миллилитрах и пополняет вес в зависимости от выпитой воды в соотношении 2мл/1г весаstatus
- если вес кота больше 9000г или меньше 1000г, то возвращается статусDEAD
, в остальных случаях возвращается статусLIVE
реализуйте счетчик котов, который будет увеличиваться каждый раз при создании нового кота.
Попробуйте создать в файле main.rb
несолько экземпляров вашего класса и повызывайте методы вашего кота, чтобы удостовериться, что кот жив.
Рекомендации:
Подумайте как лучше организовать хранение статусов кота.
не бойтесь вводить новые переменные по необходимости. Эта рекоммендация работает и для поледующих заданий.
Дополнительный материал
Last updated