Menu
Coddy logo textTech

מתודות פרטיות

חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 אונליין