استدعاء 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التحدي
سهلأكمل الأصناف. يخزّن 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
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الفئات والكائنات
العمل مع الملفاتتعريف الفئاتمتغيرات النسخةالأساليب و selfto_s و inspectمراجعة - بطاقة المكتبة7تعدد الأشكال والكتابة بأسلوب البطة
تعدد الأشكالالكتابة بأسلوب البطةالأساليب المجردةالحالات والفئاتمراجعة - طرق الدفع3أساليب ومتغيرات الأصناف
أساليب الأصنافمتغيرات كائنات الأصنافالثوابتأساليب الإنشاءمراجعة - رموز القسائمتدرّب بنفسك: مترجم Ruby عبر الإنترنت