Menu
Coddy logo textTech

Metodi privati

Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 17 di 57.

L'incapsulamento significa che un oggetto nasconde il proprio funzionamento e offre un piccolo insieme di metodi pubblici. I metodi sono pubblici per impostazione predefinita. Ogni metodo definito dopo la parola private nel corpo di una classe è privato: i metodi dell'oggetto stesso possono chiamarlo, il codice esterno no:

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

Output:

35
private method `subtotal' called for an instance of Order

All'interno della classe, un metodo privato viene chiamato senza un ricevitore o con self.. Chiamarlo su un altro oggetto, anche se appartiene alla stessa classe, non è consentito:

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

Output:

5c / 5c
private method `label' called for an instance of Coin

private può anche ricevere il nome di un metodo, e def restituisce il nome del metodo, quindi private def helper rende privato un singolo metodo proprio nel punto in cui viene definito. I metodi precedenti e successivi restano pubblici:

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)

Output:

Hello, Ada!
*waves*
[:salutation]

Mantieni privati i metodi di supporto. I metodi pubblici sono la promessa che una classe fa al resto del programma; quelli privati possono essere rinominati o rimossi in seguito senza interrompere alcun chiamante:

class Invoice
  def total              # public: chi lo chiama fa affidamento su di esso
    net + tax
  end

  private                # libero di modificarlo in seguito

  def net
    ...
  end

  def tax
    ...
  end
end
challenge icon

Sfida

Facile

Completa la classe Order. Il suo unico metodo pubblico oltre a initialize è receipt, che restituisce 3 x 12.50 = 37.50, tax 7.50, total 45.00. I metodi privati subtotal (prezzo moltiplicato per quantità), tax (il 20% del subtotale) e total calcolano i valori.

Il codice fornito legge gli ordini da righe nel formato quantity price e stampa ogni ricevuta. Poi prova a chiamare tax dall'esterno e stampa tax is private quando Ruby rifiuta.

Il tuo codice va in order.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

require_relative 'order'

# Supplied input/output code: keep it as it is
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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Ruby online