비공개 메서드
Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 17번째.
캡슐화란 객체가 작동 방식을 숨기고 소수의 공개 메서드를 제공하는 것을 의미합니다. 메서드는 기본적으로 공개됩니다. 클래스 본문에서 private라는 단어 뒤에 정의된 모든 메서드는 비공개입니다. 객체 자체의 메서드는 이를 호출할 수 있지만, 외부 코드는 호출할 수 없습니다:
class Order
def initialize(price, quantity)
@price = price
@quantity = quantity
end
def total
subtotal + shipping
end
private
def subtotal
@price * @quantity
end
def shipping
subtotal >= 50 ? 0 : 5
end
end
order = Order.new(10, 3)
puts order.total
begin
order.subtotal
rescue NoMethodError => e
puts e.message
end출력:
35
private method `subtotal' called for an instance of Order클래스 내부에서는 private 메서드를 수신자 없이 또는 self.와 함께 호출합니다. 같은 클래스의 객체라 하더라도 다른 객체에서 이를 호출하면 거부됩니다:
class Coin
def initialize(cents)
@cents = cents
end
def describe
"#{self.label} / #{label}"
end
def same_as?(other)
other.label == label
end
private
def label
"#{@cents}c"
end
end
a = Coin.new(5)
puts a.describe
begin
a.same_as?(Coin.new(5))
rescue NoMethodError => e
puts e.message
end출력:
5c / 5c
private method `label' called for an instance of Coinprivate는 메서드 이름을 받을 수도 있고, def는 메서드의 이름을 반환하므로 private def helper는 메서드가 정의된 바로 그 위치에서 하나의 메서드를 private으로 만듭니다. 위와 주변의 메서드는 public으로 유지됩니다:
class Greeter
def greet(name)
"#{salutation}, #{name}!"
end
private def salutation
"Hello"
end
def wave
"*waves*"
end
end
g = Greeter.new
puts g.greet("Ada")
puts g.wave
p Greeter.private_instance_methods(false)출력:
Hello, Ada!
*waves*
[:salutation]헬퍼는 비공개로 유지하세요. 공개 메서드는 클래스가 프로그램의 나머지 부분에 하는 약속이므로, 비공개 메서드는 호출자를 깨뜨리지 않고 나중에 이름을 바꾸거나 제거할 수 있습니다:
class Invoice
def total # public: 호출자들이 이에 의존함
net + tax
end
private # 나중에 자유롭게 변경 가능
def net
...
end
def tax
...
end
end챌린지
쉬움Order 클래스를 완성하세요. initialize를 제외하고 유일한 공개 메서드는 receipt이며, 이 메서드는 3 x 12.50 = 37.50, tax 7.50, total 45.00을 반환합니다. 비공개 메서드인 subtotal(가격 곱하기 수량), tax(소계의 20%), total이 숫자를 계산합니다.
제공된 코드는 quantity price 형식의 줄로 주문을 읽고 각 영수증을 출력합니다. 그런 다음 외부에서 tax를 호출하려고 시도하며 Ruby가 이를 거부하면 tax is private를 출력합니다.
코드는 order.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 들어 있으며 수정할 수 없습니다.
직접 해보기
require_relative 'order'
# 제공된 입력/출력 코드: 그대로 유지하세요
input = []
while (line = gets)
input << line.chomp
end
orders = input.map do |line|
quantity, price = line.split
Order.new(quantity.to_i, price.to_f)
end
orders.each { |o| puts o.receipt }
begin
orders[0].tax
puts "tax is public"
rescue NoMethodError
puts "tax is private"
end
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러