Métodos protegidos
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 18 de 57.
Um método protected fica entre público e privado. Código externo não pode chamá-lo, mas qualquer objeto da mesma classe pode chamá-lo em outro objeto. Isso permite que dois objetos comparem dados que não mostram ao restante do programa:
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
endSaída:
true
protected method `balance' called for an instance of AccountA diferença em relação a private aparece quando o receptor é outro objeto. other.balance funciona para um método protegido e falha para um método privado:
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)Saída:
3
private refused other.hiddenprotected também funciona com attr_reader, a forma usual de compartilhar um valor apenas entre objetos de uma classe, por exemplo, para decidir qual de dois objetos vence:
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).inspectSaída:
true
["Ada"]Escolha o nível mais restrito que funcione. public é para a interface da classe, protected para dados com os quais os objetos da classe se comparam, e private para todo o restante:
public # qualquer um: order.total
protected # objetos da classe: other.balance dentro de Account
private # apenas o próprio objeto: subtotal, self.subtotalDesafio
FácilComplete a classe Account. O saldo pode ser lido apenas por outras contas: torne seu leitor protegido. richer_than?(other) compara os saldos, transfer_to(other, amount) transfere dinheiro para outra conta por meio do método protegido receive(amount) da outra conta e retorna true, ou retorna false quando o saldo é insuficiente. to_s retorna apenas o nome do proprietário.
O código fornecido lê os dois proprietários e saldos, depois os comandos transfer a b 50, exibindo ok ou refused. Em seguida, exibe Ada is richer (ou Bo is richer, ou equal) e, por fim, tenta ler balance de fora, exibindo balance is protected quando o Ruby recusa.
Seu código deve ficar em account.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'account'
# Código de entrada/saída fornecido: mantenha-o como está
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
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de Ruby online