Phương thức riêng tư
Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 17 trên 57.
Tính đóng gói (encapsulation) nghĩa là một đối tượng ẩn cách nó hoạt động và cung cấp một tập hợp nhỏ các phương thức công khai. Các phương thức mặc định là công khai. Mọi phương thức được định nghĩa sau từ private trong thân lớp đều là phương thức riêng tư: các phương thức của chính đối tượng có thể gọi phương thức đó, còn code bên ngoài thì không thể:
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Đầu ra:
35
private method `subtotal' called for an instance of OrderBên trong lớp, một phương thức riêng tư được gọi mà không có đối tượng nhận hoặc với self.. Nếu gọi phương thức đó trên một đối tượng khác, kể cả đối tượng cùng lớp, Ruby sẽ từ chối:
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Đầu ra:
5c / 5c
private method `label' called for an instance of Coinprivate cũng có thể nhận tên một phương thức, còn def trả về tên của phương thức, vì vậy private def helper khiến một phương thức trở thành riêng tư ngay tại nơi nó được định nghĩa. Các phương thức phía trên và xung quanh vẫn là công khai:
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)Đầu ra:
Hello, Ada!
*waves*
[:salutation]Giữ các hàm hỗ trợ ở chế độ riêng tư. Các phương thức (method) công khai là lời hứa mà một lớp đưa ra với phần còn lại của chương trình; bạn có thể đổi tên hoặc xóa các phương thức riêng tư về sau mà không làm hỏng bất kỳ bên gọi nào:
class Invoice
def total # public: mã gọi phụ thuộc vào phương thức này
net + tax
end
private # có thể tùy ý thay đổi sau
def net
...
end
def tax
...
end
endThử thách
DễHoàn thiện lớp Order. Phương thức công khai duy nhất ngoài initialize là receipt, trả về 3 x 12.50 = 37.50, tax 7.50, total 45.00. Các phương thức riêng tư subtotal (giá nhân với số lượng), tax (20% của subtotal) và total tính các con số.
Code được cung cấp đọc các đơn hàng theo từng dòng quantity price và in từng biên nhận. Sau đó, code thử gọi tax từ bên ngoài và in tax is private khi Ruby từ chối.
Code của bạn nằm trong order.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
require_relative 'order'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
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
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpBiến instancePhương thức và selfto_s và inspectÔn tập: thẻ thư viện4Tính đóng gói
Phương thức riêng tưPhương thức được bảo vệPhương thức thiết lập riêng tưBảo vệ trạng tháiÔn tập: máy bán hàng tự động7Tính đa hình và duck typing
Tính đa hìnhDuck typingPhương thức trừu tượngcase và lớpÔn tập: phương thức thanh toán2Phương thức truy cập và self
Phương thức đọc và ghiPhương thức gán tùy chỉnhself trong phương thứcĐịnh danh và tính bằng nhauÔn tập: Danh sách liên hệTự luyện tập: Trình biên dịch Ruby online