Menu
CoddyTech

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

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