Класи - центральне поняття обʼєктно-орієнтованого програмування. У Crystal усе є обʼєктом, кожен обʼєкт має тип і може відповідати на деякі методи. Класи - це креслення для створення обʼєктів: вони задають початкові значення для стану, як-от змінні, і реалізації поведінки, як-от методи. Обʼєкти - це екземпляри класу, які зберігають усі змінні екземпляра та стани.
Клас визначають за допомогою ключового слова class, після якого йде назва класу, записана в UpperCamelCase.
class Account
end
Щоб створити екземпляр класу, викликаємо назву класу за допомогою методу new.
class Account
end
account = Account.new
У наведеному вище прикладі змінна account - це екземпляр класу Account.
Під час створення екземпляра спеціальний метод initialize виконує роль конструктора.
Його викликають під час створення екземпляра.
Конструктор дає змогу задати початковий стан екземпляра.
Метод initialize може приймати аргументи, які передаються під час створення екземпляра.
class Account
def initialize(number)
5 + number # => 9
end
end
Account.new(4)
Метод initialize не може повертати значення вручну; натомість new повертає щойно створений екземпляр.
class Account
def initialize(number)
5 + number
end
end
Account.new(4)
# => #<Account:0x7f5dc33dcea0>
Метод екземпляра - це метод, доступний екземпляру класу, який можна викликати на цьому екземплярі.
Методи екземпляра визначають за допомогою ключового слова def, після якого йде назва методу.
Їх визначають усередині визначення класу.
class Account
def balance
100
end
end
account = Account.new
account.balance # => 100
Змінні екземпляра - це змінні, доступні в усіх методах екземпляра.
Щоб отримати доступ до змінної екземпляра, треба визначити метод екземпляра.
Їх можна ініціалізувати в методі initialize.
Їх визначають за допомогою префікса @.
class Account
def initialize
@balance = 100
end
def balance
@balance
end
end
account = Account.new
account.balance
# => 100
Змінні екземпляра також можна визначити всередині визначення класу.
class Account
@age = 0
end
Змінні екземпляра можна ініціалізувати аргументом, переданим у метод initialize.
Оскільки Crystal не може вивести тип аргументу, використаного під час ініціалізації, його потрібно вказати.
Докладніше про це можна прочитати тут: виведення типу.
Щоб указати тип змінної, можна використати символ :, після якого йде тип.
Наприклад, щоб створити змінну екземпляра з назвою balance типу Int32, можна зробити так: @balance : Int32.
Або, щоб створити змінну екземпляра з назвою raining типу Bool, можна зробити так: @raining : Bool.
Є кілька способів це зробити: або оголосити аргумент із типом у методі initialize, а потім присвоїти змінній екземпляра значення аргументу, як у наступному прикладі:
class Account
def initialize(balance : Int32)
@balance = balance
end
def balance
@balance
end
end
account = Account.new(1)
account_2 = Account.new(5)
account.balance
# => 1
account_2.balance
# => 5
Інший спосіб - оголосити тип змінної екземпляра у визначенні класу у формі: @<variable> : <Type>, як у наступному прикладі:
class Weather
@raining : Bool
def initialize(raining)
@raining = raining
end
def raining
@raining
end
end
weather = Weather.new(true)
weather.raining
# => true
Методи можуть змінювати змінні екземпляра. Ці методи можна викликати на екземплярі класу. Коли метод змінює змінну екземпляра, ця зміна доступна лише в тому екземплярі класу, на якому його викликали.
class Account
def initialize(balance : Int32)
@balance = balance
end
def withdraw(amount)
@balance -= amount
end
def balance
@balance
end
end
account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10
account_2.balance
# => 10
account.withdraw(5)
account.balance
# => 5
account_2.balance
# => 10
Методи класу - це методи, визначені для класу, а не для його екземплярів.
Вони дають змогу створювати методи, які не залежать від стану екземпляра.
Їх визначають за допомогою ключового слова def, після якого йде self.<method name>.
self - це посилання на простір імен, з якого викликають self.
У цьому випадку він указує на клас Account.
Це те саме, якби написати Account., але краще використовувати self..
class Account
def self.balance
100
end
end
Account.balance
# => 100
Друг Йоганнес обожнює збирати саморобну апаратуру (DIY, тобто «зроби сам»). Він щойно зібрав соковижималку і дуже нею захоплений. Мета Йоганнеса - щоранку готувати свіжий сік.
У соковижималки Йоганнеса багато цікавих можливостей. Наприклад, вбудована система вимірювання, яка показує, скільки соку в склянці. Є в неї й таймер, який підказує, як довго працює машина.
Йоганнес не дуже добре програмує, але хоче написати програму для керування машиною. Тож він і попросив допомогти.
У машини є індикатор debug. Це простий механізм: якщо машина має живлення, індикатор debug горить. Програма запуститься, лише якщо індикатор debug горить.
Цей метод має бути методом класу з назвою JuiceMaker.
Визначте метод класу JuiceMaker.debug_light_on?, який повертає true.
JuiceMaker.debug_light_on?
#=> true
Коли машина вмикається, має створюватися екземпляр класу з назвою JuiceMaker.
Машина повинна мати ініціалізований стан.
Ініціалізований стан має містити таку інформацію:
false.Визначте ініціалізований стан, який приймає кількість соку в склянці як параметр, і сконструюйте цей стан.
Ініціалізований стан має містити змінну екземпляра @running, встановлену в false, і змінну екземпляра @fluid, значення якої базується на аргументі, переданому під час ініціалізації класу.
JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>
Машину можна вмикати й вимикати.
Потрібно визначити метод, який вмикає машину.
Коли машина вмикається, стан роботи має встановлюватися в true.
Визначте метод JuiceMaker#start, який вмикає машину.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>
Машина повинна вміти повідомляти свій стан.
Він має повертати true, якщо машина працює, і false, якщо машина не працює.
Визначте метод JuiceMaker#running?, який повертає стан машини.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker.running?
#=> true
Машина може додавати сік у склянку. Машина вміє визначати, скільки соку додано в склянку. Але їй потрібна допомога, щоб дізнатися, скільки соку в склянці після додавання.
Визначте метод JuiceMaker#add_fluid, який приймає кількість доданого соку як параметр і оновлює кількість соку в склянці.
juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>
Машину можна вмикати й вимикати.
Потрібно визначити метод, який вимикає машину.
Цей метод викликатиметься лише тоді, коли машина працює.
Коли машина вимикається, стан роботи має встановлюватися в false.
Також машині потрібна допомога, щоб визначити, скільки соку в склянці після вимкнення.
Машина витрачає пʼять одиниць соку за хвилину.
Визначте метод JuiceMaker#stop, який приймає кількість хвилин роботи машини як параметр і повертає кількість соку в склянці після вимкнення машини.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>
juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
Зареєструйтеся на Exercism, щоб вивчати й опановувати Crystal, а також 26 концепцій142 вправи та справжнє наставництво від людей, і все це безкоштовно.