보호된 메서드
Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 18번째.
protected 메서드는 public과 private의 중간에 해당합니다. 코드 외부에서는 이 메서드를 호출할 수 없지만, 같은 클래스의 모든 객체는 다른 객체에서 이 메서드를 호출할 수 있습니다. 이를 통해 두 객체는 프로그램의 나머지 부분에 표시하지 않는 데이터를 서로 비교할 수 있습니다:
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
end출력:
true
protected method `balance' called for an instance of Accountprivate와의 차이는 수신자가 다른 객체일 때 드러납니다. other.balance는 protected 메서드에서는 작동하지만 private 메서드에서는 실패합니다:
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)출력:
3
private refused other.hiddenprotected는 attr_reader와도 함께 사용할 수 있습니다. 이는 일반적으로 한 클래스의 객체들 사이에서만 값을 공유하는 방법이며, 예를 들어 두 객체 중 어느 것이 이기는지 결정할 때 사용할 수 있습니다.
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).inspect출력:
true
["Ada"]작동하는 가장 좁은 수준을 선택하세요. public은 클래스의 인터페이스에, protected는 클래스의 객체들이 서로 비교하는 데이터에, private은 그 외의 모든 것에 사용합니다:
public # 누구나: order.total
protected # 클래스의 객체들: Account 내부의 other.balance
private # 객체 자신만: subtotal, self.subtotal챌린지
쉬움Account 클래스를 완성하세요. 잔액은 다른 계정만 읽을 수 있어야 하므로, 해당 리더를 protected로 만드세요. richer_than?(other)는 잔액을 비교하고, transfer_to(other, amount)는 다른 계정의 protected 메서드인 receive(amount)를 통해 다른 계정으로 돈을 이동한 후 true를 반환합니다. 잔액이 부족하면 false를 반환합니다. to_s는 소유자의 이름만 반환합니다.
제공된 코드는 두 소유자와 잔액을 읽은 다음 transfer a b 50 명령을 처리하며, ok 또는 refused를 출력합니다. 그런 다음 Ada is richer(또는 Bo is richer, 또는 equal)를 출력하고, 마지막으로 외부에서 balance를 읽으려고 시도하여 Ruby가 거부하면 balance is protected를 출력합니다.
코드는 account.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 들어 있으며 수정할 수 없습니다.
직접 해보기
require_relative 'account'
# 제공된 입력/출력 코드: 그대로 유지하세요
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
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러