Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الأساليب الخاصة

جزء من قسم البرمجة كائنية التوجه في رحلة Ruby على Coddy. الدرس 17 من 57.

التغليف يعني أن الكائن يخفي كيفية عمله ويقدّم مجموعة صغيرة من الأساليب العامة. تكون الأساليب عامةً افتراضيًا. كل أسلوب يُعرَّف بعد الكلمة private في جسم الفئة يكون خاصًا: يمكن لأساليب الكائن نفسه استدعاؤه، بينما لا يستطيع الكود الخارجي ذلك:

class Order
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def total
    subtotal + shipping
  end

  private

  def subtotal
    @price * @quantity
  end

  def shipping
    subtotal >= 50 ? 0 : 5
  end
end

order = Order.new(10, 3)
puts order.total
begin
  order.subtotal
rescue NoMethodError => e
  puts e.message
end

الناتج:

35
private method `subtotal' called for an instance of Order

داخل الصنف، تُستدعى طريقة خاصة دون مستقبِل أو باستخدام self.. ويُرفض استدعاؤها على كائن آخر، حتى لو كان من الصنف نفسه:

class Coin
  def initialize(cents)
    @cents = cents
  end

  def describe
    "#{self.label} / #{label}"
  end

  def same_as?(other)
    other.label == label
  end

  private

  def label
    "#{@cents}c"
  end
end

a = Coin.new(5)
puts a.describe
begin
  a.same_as?(Coin.new(5))
rescue NoMethodError => e
  puts e.message
end

الناتج:

5c / 5c
private method `label' called for an instance of Coin

يمكن أن تأخذ private أيضًا اسمَ طريقة، ويُرجع def اسمَ الطريقة، لذا فإن private def helper يجعل طريقة واحدة خاصة في الموضع الذي عُرّفت فيه مباشرةً. وتبقى الطرق الموجودة أعلاه وحولها عامةً:

class Greeter
  def greet(name)
    "#{salutation}, #{name}!"
  end

  private def salutation
    "Hello"
  end

  def wave
    "*waves*"
  end
end

g = Greeter.new
puts g.greet("Ada")
puts g.wave
p Greeter.private_instance_methods(false)

الناتج:

Hello, Ada!
*waves*
[:salutation]

اجعل الدوال المساعدة خاصة. فالأساليب العامة هي الوعد الذي يقدّمه الصنف لبقية البرنامج؛ ويمكن إعادة تسمية الأساليب الخاصة أو إزالتها لاحقًا من دون التسبب في تعطّل أي مستدعٍ:

class Invoice
  def total              # public: يعتمد عليه المستدعون
    net + tax
  end

  private                # حر للتغيير لاحقاً

  def net
    ...
  end

  def tax
    ...
  end
end
challenge icon

التحدي

سهل

أكمل الصنف Order. طريقته العامة الوحيدة إلى جانب initialize هي receipt، التي تُرجع 3 x 12.50 = 37.50, tax 7.50, total 45.00. تحسب الطرق الخاصة subtotal (السعر مضروبًا في الكمية) وtax (20% من المجموع الفرعي) وtotal الأرقام.

يقرأ الكود المُزوَّد الطلبات على هيئة أسطر quantity price ويطبع كل إيصال. ثم يحاول استدعاء tax من الخارج ويطبع tax is private عندما يرفض Ruby ذلك.

ضع الكود الخاص بك في order.rb. يحتوي main.rb على كود الإدخال/الإخراج المُزوَّد، ولا يمكن تعديله.

جرّب بنفسك

require_relative 'order'

# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input = []
while (line = gets)
  input << line.chomp
end
orders = input.map do |line|
  quantity, price = line.split
  Order.new(quantity.to_i, price.to_f)
end
orders.each { |o| puts o.receipt }
begin
  orders[0].tax
  puts "tax is public"
rescue NoMethodError
  puts "tax is private"
end
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Ruby عبر الإنترنت