Menu
CoddyTech

تجاوز الدوال

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

يمكن للفئة الفرعية تجاوز طريقة من خلال تعريف طريقة بالاسم نفسه. يبحث Ruby عن طريقة في الفئة الخاصة بالكائن أولًا، ثم في الفئة الفائقة فقط، لذا تكون الأولوية لنسخة الفئة الفرعية:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Fish < Animal
end

puts Dog.new.speak
puts Fish.new.speak

الناتج:

Woof
...

تستخدم الطريقة الفائقة التي تستدعي طريقة أخرى النسخة المتجاوزة منها مع كائنات الفئات الفرعية. تُكتب الطريقة المشتركة مرة واحدة، ولا تغيّر كل فئة فرعية إلا الجزء المختلف:

class Animal
  def initialize(name)
    @name = name
  end

  def introduce
    "#{@name} says #{speak}"
  end

  def speak
    "..."
  end
end

class Cat < Animal
  def speak
    "Meow"
  end
end

puts Cat.new("Tom").introduce
puts Animal.new("Thing").introduce

الناتج:

Tom says Meow
Thing says ...

يؤدي تجاوز to_s في فئة فرعية إلى تغيير طريقة الطباعة في تلك الفئة الفرعية فقط. أما الطرق التي لا تتجاوزها، فتظل موروثة من الفئة الفائقة:

class Item
  def initialize(name, price)
    @name = name
    @price = price
  end

  def to_s
    format("%s %.2f", @name, @price)
  end
end

class SaleItem < Item
  def to_s
    format("%s %.2f (sale)", @name, @price * 0.8)
  end
end

puts Item.new("Lamp", 20)
puts SaleItem.new("Lamp", 20)

الناتج:

Lamp 20.00
Lamp 16.00 (sale)

الترتيب الذي يبحث به Ruby يُسمّى الأسلاف للصنف: الصنف نفسه، ثم صنفه الفائق، وهكذا وصولًا إلى Object. أول صنف في هذه القائمة يعرّف الطريقة هو الذي يوفّرها:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Puppy < Dog
end

puts Puppy.new.speak
p Puppy.ancestors.take(3)

الناتج:

Woof
[Puppy, Dog, Animal]
challenge icon

التحدي

سهل

أكمل أصناف الرواتب. يخزّن Employee قيمة name، ويحتوي على pay(hours) التي تُرجع hours * 20، وpayslip(hours) التي تُرجع Ada: 800 باستخدام pay. يعيد Manager تعريف pay بقيمة ثابتة مقدارها 1500 مهما كانت الساعات. ويعيد Intern تعريف pay باستخدام hours * 12، على ألا تتجاوز النتيجة 300. تُعرَّف payslip في Employee فقط.

يقرأ الكود المقدَّم أسطرًا مثل employee Ada 40 أو manager Bo 50 أو intern Cy 20، وينشئ الكائن المطابق ويطبع قسيمة راتبه، ثم يطبع إجمالي الأجور.

ضع كودك في employee.rb وmanager.rb وintern.rb. يحتوي main.rb على كود الإدخال/الإخراج المقدَّم، ولا يمكن تعديله.

جرّب بنفسك

require_relative 'employee'
require_relative 'manager'
require_relative 'intern'

# كود الإدخال والإخراج المقدَّم: اتركه كما هو
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "employee" => Employee, "manager" => Manager, "intern" => Intern }
total = 0
input.each do |line|
  kind, name, hours = line.split
  worker = kinds[kind].new(name)
  puts worker.payslip(hours.to_i)
  total += worker.pay(hours.to_i)
end
puts "total: #{total}"
quiz iconاختبر نفسك

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

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

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