Métodos protegidos
Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 18 de 57.
Un método protected se encuentra entre lo público y lo privado. El código externo no puede llamarlo, pero cualquier objeto de la misma clase puede llamarlo sobre otro objeto. Esto permite que dos objetos comparen datos que no muestran al resto del 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
endSalida:
true
protected method `balance' called for an instance of AccountLa diferencia con private se manifiesta cuando el receptor es otro objeto. other.balance funciona para un método protegido y falla para uno 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)Salida:
3
private refused other.hiddenprotected también funciona con attr_reader, la forma habitual de compartir un valor únicamente entre objetos de una clase, por ejemplo, para decidir cuál de dos objetos gana:
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).inspectSalida:
true
["Ada"]Elige el nivel más restringido que funcione. public es para la interfaz de la clase, protected para los datos que los objetos de la clase comparan entre sí y private para todo lo demás:
public # cualquiera: order.total
protected # objetos de la clase: other.balance dentro de Account
private # solo el objeto mismo: subtotal, self.subtotalDesafío
FácilCompleta la clase Account. El saldo solo debe poder ser leído por otras cuentas: haz que su lector sea protected. richer_than?(other) compara los saldos, transfer_to(other, amount) transfiere dinero a otra cuenta mediante el método protected de la otra cuenta, receive(amount), y devuelve true, o devuelve false cuando el saldo es demasiado bajo. to_s devuelve únicamente el nombre del propietario.
El código proporcionado lee los dos propietarios y sus saldos, después los comandos transfer a b 50, e imprime ok o refused. Después imprime Ada is richer (o Bo is richer, o equal) y, finalmente, intenta leer balance desde fuera, imprimiendo balance is protected cuando Ruby lo rechaza.
Tu código debe ir en account.rb. main.rb contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
require_relative 'account'
# Código de entrada/salida suministrado: déjalo tal 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 lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesVariables de instanciaMétodos y selfto_s e inspectRepaso: tarjeta de biblioteca4Encapsulación
Métodos privadosMétodos protegidosAsignadores privadosProtección del estadoRepaso: máquina expendedora7Polimorfismo y tipado pato
PolimorfismoTipado patoMétodos abstractoscase y clasesRepaso: métodos de pago2Accesores y self
Lectores y escritoresSetters personalizadosself en los métodosIdentidad e igualdadRepaso: lista de contactos5Herencia
SubclasesSobrescritura de métodosLlamar a superis_a? y ancestrosRepaso - Nómina del personal8Métodos especiales
Igualdad y hashMétodos de operadoresIndexación y adiciónColecciones personalizadasRepaso: fracciones11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Compilador de Ruby online