Metodi protetti
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 18 di 57.
Un metodo protetto si colloca tra pubblico e privato. Il codice esterno non può chiamarlo, ma qualsiasi oggetto della stessa classe può chiamarlo su un altro oggetto. Questo permette a due oggetti di confrontare dati che non mostrano al resto del programma:
class Account
def initialize(owner, balance)
@owner = owner
@balance = balance
end
def richer_than?(other)
balance > other.balance
end
protected
def balance
@balance
end
end
ada = Account.new("Ada", 500)
bo = Account.new("Bo", 300)
puts ada.richer_than?(bo)
begin
ada.balance
rescue NoMethodError => e
puts e.message
endOutput:
true
protected method `balance' called for an instance of AccountLa differenza rispetto a private si nota quando il ricevente è un altro oggetto. other.balance funziona per un metodo protetto e non funziona per uno privato:
class Sample
def initialize(n)
@n = n
end
def compare_protected(other)
other.guarded + guarded
end
def compare_private(other)
other.hidden + hidden
rescue NoMethodError
"private refused other.hidden"
end
protected
def guarded
@n
end
private
def hidden
@n
end
end
a = Sample.new(1)
b = Sample.new(2)
puts a.compare_protected(b)
puts a.compare_private(b)Output:
3
private refused other.hiddenprotected funziona anche con attr_reader, il modo usuale per condividere un valore solo tra oggetti di una stessa classe, ad esempio per decidere quale di due oggetti vince:
class Player
attr_reader :name
def initialize(name, rating)
@name = name
@rating = rating
end
def stronger?(other)
rating > other.rating
end
protected
attr_reader :rating
end
a = Player.new("Ada", 1200)
b = Player.new("Bo", 1100)
puts a.stronger?(b)
puts [a, b].select { |pl| pl.stronger?(b) }.map(&:name).inspectOutput:
true
["Ada"]Scegli il livello più restrittivo che funziona. public è per l’interfaccia della classe, protected per i dati che gli oggetti della classe confrontano tra loro e private per tutto il resto:
public # chiunque: order.total
protected # oggetti della classe: other.balance all'interno di Account
private # solo l'oggetto stesso: subtotal, self.subtotalSfida
FacileCompleta la classe Account. Il saldo è leggibile solo dagli altri account: rendi protetto il relativo accessor. richer_than?(other) confronta i saldi, transfer_to(other, amount) trasferisce denaro a un altro account tramite il metodo protetto dell'altro account receive(amount) e restituisce true, oppure restituisce false quando il saldo è insufficiente. to_s restituisce solo il nome del proprietario.
Il codice fornito legge i nomi dei due proprietari e i rispettivi saldi, poi i comandi transfer a b 50, stampando ok oppure refused. Poi stampa Ada is richer (oppure Bo is richer, oppure equal) e infine prova a leggere balance dall'esterno, stampando balance is protected quando Ruby rifiuta.
Il tuo codice va in account.rb. main.rb contiene il codice fornito per input/output e non può essere modificato.
Provalo tu
require_relative 'account'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
accounts = input[0..1].map do |line|
owner, balance = line.split
Account.new(owner, balance.to_i)
end
a, b = accounts
input.drop(2).each do |line|
_, from, to, amount = line.split
source = from == "a" ? a : b
target = to == "a" ? a : b
puts source.transfer_to(target, amount.to_i) ? "ok" : "refused"
end
if a.richer_than?(b) then puts "#{a} is richer"
elsif b.richer_than?(a) then puts "#{b} is richer"
else puts "equal"
end
begin
a.balance
puts "balance is public"
rescue NoMethodError
puts "balance is protected"
end
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
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libriEsercitati da solo: Compilatore Ruby online