الأساليب المحمية
جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 18 من 57.
تقع الطريقة protected بين public وprivate. لا يمكن للكود الخارجي استدعاؤها، لكن يمكن لأي كائن من الفئة نفسها استدعاؤها على كائن آخر منها. يتيح ذلك لكائنين مقارنة بيانات لا يعرضانها لبقية البرنامج:
class Account
def initialize(owner, balance)
@owner = owner
@balance = balance
end
def richer_than?(other)
balance > other.balance
end
protected
def balance
@balance
end
end
ada = Account.new("Ada", 500)
bo = Account.new("Bo", 300)
puts ada.richer_than?(bo)
begin
ada.balance
rescue NoMethodError => e
puts e.message
endالمخرجات:
true
protected method `balance' called for an instance of Accountيظهر الفرق عن private عندما يكون المستقبل كائنًا آخر. يعمل other.balance مع طريقة محمية ويفشل مع طريقة خاصة:
class Sample
def initialize(n)
@n = n
end
def compare_protected(other)
other.guarded + guarded
end
def compare_private(other)
other.hidden + hidden
rescue NoMethodError
"private refused other.hidden"
end
protected
def guarded
@n
end
private
def hidden
@n
end
end
a = Sample.new(1)
b = Sample.new(2)
puts a.compare_protected(b)
puts a.compare_private(b)الناتج:
3
private refused other.hiddenتعمل protected أيضًا مع attr_reader، وهي الطريقة المعتادة لمشاركة قيمة بين كائنات فئة واحدة فقط، مثلًا لتحديد أيّ كائنين يفوز:
class Player
attr_reader :name
def initialize(name, rating)
@name = name
@rating = rating
end
def stronger?(other)
rating > other.rating
end
protected
attr_reader :rating
end
a = Player.new("Ada", 1200)
b = Player.new("Bo", 1100)
puts a.stronger?(b)
puts [a, b].select { |pl| pl.stronger?(b) }.map(&:name).inspectالناتج:
true
["Ada"]اختر أضيق مستوى ينجح. public لواجهة الصنف، وprotected للبيانات التي تقارنها كائنات الصنف مع بعضها، وprivate لكل ما عدا ذلك:
public # أي شخص: order.total
protected # كائنات الصنف: other.balance داخل Account
private # الكائن نفسه فقط: subtotal, self.subtotalالتحدي
سهلأكمل الصنف Account. لا يمكن قراءة الرصيد إلا من قِبل الحسابات الأخرى: اجعل قارئه محميًا. تقارن richer_than?(other) الأرصدة، وتنقل transfer_to(other, amount) المال إلى حساب آخر من خلال الطريقة المحمية receive(amount) الخاصة بالحساب الآخر، وتُرجع true، أو تُرجع false عندما يكون الرصيد منخفضًا جدًا. تُرجع to_s اسم المالك فقط.
يقرأ الكود المزوَّد اسمي المالكين ورصيديهما، ثم أوامر transfer a b 50، ويطبع ok أو refused. ثم يطبع Ada is richer (أو Bo is richer، أو equal) ويحاول أخيرًا قراءة balance من الخارج، ويطبع balance is protected عندما يرفض Ruby ذلك.
ضع الكود في account.rb. يحتوي main.rb على كود الإدخال/الإخراج المزوَّد ولا يمكن تعديله.
جرّب بنفسك
require_relative 'account'
# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input = []
while (line = gets)
input << line.chomp
end
accounts = input[0..1].map do |line|
owner, balance = line.split
Account.new(owner, balance.to_i)
end
a, b = accounts
input.drop(2).each do |line|
_, from, to, amount = line.split
source = from == "a" ? a : b
target = to == "a" ? a : b
puts source.transfer_to(target, amount.to_i) ? "ok" : "refused"
end
if a.richer_than?(b) then puts "#{a} is richer"
elsif b.richer_than?(a) then puts "#{b} is richer"
else puts "equal"
end
begin
a.balance
puts "balance is public"
rescue NoMethodError
puts "balance is protected"
end
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت