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

استدعاء super

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

داخل طريقة مُعاد تعريفها، تستدعي super نسخة الفئة الأب من الطريقة نفسها. ويمكن للفئة الفرعية البناء على النتيجة بدلًا من تكرارها:

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

class LoudGreeter < Greeter
  def greet(name)
    super.upcase + "!"
  end
end

puts LoudGreeter.new.greet("Ada")

الناتج:

HELLO, ADA!

الاستخدام الأكثر شيوعًا هو initialize: يأخذ الصنف الفرعي قيمة إضافية، ويمرّر القيم المشتركة إلى الصنف الفائق باستخدام super(...) ويخزّن قيمته الخاصة:

class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end
end

class Student < Person
  attr_reader :school

  def initialize(name, age, school)
    super(name, age)
    @school = school
  end
end

s = Student.new("Ada", 20, "MIT")
puts "#{s.name}, #{s.age}, #{s.school}"

الناتج:

Ada, 20, MIT

تختلف الأشكال الثلاثة فيما تمرّره. يمرّر super المجرّد الوسائط نفسها التي استقبلتها الطريقة الحالية؛ ويمرّر super() لا شيء؛ ويمرّر super(a, b) تلك الوسائط تحديدًا:

class Base
  def show(*args)
    "Base got #{args.inspect}"
  end
end

class Child < Base
  def show(a, b)
    [super, super(), super(b)].join(" | ")
  end
end

puts Child.new.show(1, 2)

الناتج:

Base got [1, 2] | Base got [] | Base got [2]

يمكن تشغيل super في أي مكان داخل الطريقة، أو تشغيله فقط عند تحقق شرط. عندما تأخذ initialize في الفئة الفرعية معاملات أخرى غير معاملات الفئة الأب، فإن super المجردة تمرر المعاملات الخاطئة، مما يؤدي إلى ArgumentError شائع:

class Logger
  def log(message)
    puts "LOG #{message}"
  end
end

class QuietLogger < Logger
  def log(message)
    super unless message.start_with?("debug")
  end
end

logger = QuietLogger.new
logger.log("started")
logger.log("debug x=1")
logger.log("done")

المخرجات:

LOG started
LOG done
challenge icon

التحدي

سهل

أكمل الأصناف. يخزّن Person كلًا من name وage، وتُرجع to_s الخاصة به Ada (36). يضيف Student مدرسةً: تمرّر initialize الاسم والعمر إلى super، وتُرجع to_s الخاصة به Ada (20), studies at MIT، المبنية من super. يضيف Teacher مادةً بالطريقة نفسها ويُرجع Bo (45), teaches maths.

يقرأ الكود المُقدَّم الأسطر person Ada 36 أو student Ada 20 MIT أو teacher Bo 45 maths ويطبع كل كائن.

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

جرّب بنفسك

require_relative 'person'
require_relative 'student'
require_relative 'teacher'

# كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
input = []
while (line = gets)
  input << line.chomp
end
input.each do |line|
  kind, name, age, extra = line.split
  person = case kind
           when "student" then Student.new(name, age.to_i, extra)
           when "teacher" then Teacher.new(name, age.to_i, extra)
           else Person.new(name, age.to_i)
           end
  puts person
end
quiz iconاختبر نفسك

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

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

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