Darsliklar Ruby Sinflar / Obyektlar

Ruby Ruby Sinflar / Obyektlar

Sinflar va obyektlar mavzusini davom ettirib, obyektning ichki holatiga tashqaridan qanday xavfsiz kirish va o’zgartirish mumkinligini ko’ramiz. Ruby’da C++ yoki Python’dan farqli, instans o’zgaruvchisiga (@ism) sinf tashqarisidan hech qachon to’g’ridan-to’g’ri kirib bo’lmaydi — buning uchun har doim metod kerak.

Instans metodisinf ichida e’lon qilingan, faqat shu sinfdan yaratilgan obyekt orqali chaqiriladigan metod. Obyektning @ bilan boshlangan o’zgaruvchilariga faqat shunday metodlar orqali kirish mumkin.

Qo’lda yozilgan getter va setter

Instans o’zgaruvchisini o’qish va yozish uchun odatiy Ruby metodlari yozamiz. Diqqat: setter metod nomi = bilan tugaydi — bu maxsus sintaksisga ruxsat beradi:

class Foydalanuvchi
  def ism=(qiymat)
    @ism = qiymat
  end

  def ism
    @ism
  end
end

a = Foydalanuvchi.new
b = Foydalanuvchi.new

a.ism = "Farrux"
b.ism = "Master Sherkulov"

puts a.ism
puts b.ism
Farrux
Master Sherkulov

def ism=(qiymat) — nomi = bilan tugagani uchun Ruby a.ism = "Farrux" yozuvini a.ism=("Farrux") chaqiruviga avtomatik aylantiradi — bu oddiy o’zgaruvchiga qiymat berish kabi tabiiy ko’rinadi, aslida esa metod chaqiruvi. def ism esa qiymatni o’qib qaytaradi.

Instans o’zgaruvchisiga to’g’ridan-to’g’ri kirish imkonsizligi

Getter metodi yozilmagan bo’lsa, tashqaridan @ o’zgaruvchisiga hech qanday yo’l bilan kira olmaysiz:

class Mahsulot
  def narx=(qiymat)
    @narx = qiymat
  end
end

m = Mahsulot.new
m.narx = 50000

begin
  puts m.narx
rescue NoMethodError => xato
  puts "Xato turi: #{xato.class}"
end
Xato turi: NoMethodError

Setter yozilgan, lekin getter yozilmagan — shuning uchun m.narx chaqiruvi xato beradi: bunday metod umuman mavjud emas. Bu — Ruby’da enkapsulatsiya nima uchun “standart holat” deb atalishining sababi: siz ochib bermaguningizcha, hech narsa tashqariga ko’rinmaydi. (begin...rescue — xatoni ushlash usuli, uni keyinroq alohida darsda chuqur ko’ramiz.)

self — joriy obyektga ishora

Sinf ichida self joriy obyektning o’zini bildiradi. U, ayniqsa, obyekt ichidan o’zining boshqa metodini chaqirishda ishlatiladi:

class Hisob
  def balans=(qiymat)
    @balans = qiymat
  end

  def balans
    @balans
  end

  def ikkilantir
    self.balans = balans * 2
  end
end

h = Hisob.new
h.balans = 100
h.ikkilantir
puts h.balans
200

self.balans = ... — setterni aniq chaqirish uchun self zarur (balans = ... yozilsa, Ruby buni yangi lokal o’zgaruvchi deb tushunган bo’lardi, setter emas). O’ng tomondagi balans esa — getter chaqiruvi, bu yerda self yozish shart emas.

Bir nechta instans o’zgaruvchisi

Real obyektlar odatda bir nechta holatni birga saqlaydi:

class Kitob
  def sozla(nomi, sahifa)
    @nomi = nomi
    @sahifa = sahifa
  end

  def malumot
    "#{@nomi} — #{@sahifa} bet"
  end
end

k = Kitob.new
k.sozla("Ruby asoslari", 240)
puts k.malumot
Ruby asoslari — 240 bet

sozla metodi ikkita instans o’zgaruvchisini birdaniga o’rnatdi. Ammo obyektni ikki bosqichda (.new, keyin .sozla) tayyorlash noqulay — keyingi darsda buni bir qadamga tushiradigan konstruktorni ko’ramiz.