Menu
Coddy logo textTech

קריאה ל־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 אונליין