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 protegido 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 mesma 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 que os objetos da classe comparam entre si, e private para todo o resto:
public # qualquer pessoa: 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 só pode ser lido por outras contas: torne o leitor dele 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 titular.
O código fornecido lê os dois titulares e seus saldos e depois os comandos transfer a b 50, imprimindo ok ou refused. Em seguida, imprime Ada is richer (ou Bo is richer, ou equal) e, por fim, tenta ler balance de fora da classe, imprimindo balance is protected quando o Ruby recusa.
Seu código fica em account.rb. main.rb contém o código de entrada/saída fornecido 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