Menu
CoddyTech

Phương thức và self

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 4 trên 57.

Một phương thức có thể gọi một phương thức khác của cùng đối tượng mà không cần viết đối tượng nhận. Ruby gửi lời gọi đến đối tượng hiện tại, nhờ đó các phương thức có thể kết hợp với nhau:

class Order
  def initialize(price, quantity)
    @price = price
    @quantity = quantity
  end

  def subtotal
    @price * @quantity
  end

  def shipping
    subtotal >= 50 ? 0 : 5
  end

  def total
    subtotal + shipping
  end
end

puts Order.new(10, 3).total
puts Order.new(20, 3).total

Đầu ra:

35
60

Bên trong một phương thức, self là đối tượng mà phương thức được gọi trên đó. Phương thức trả về self cho phép bên gọi nối tiếp nhiều lời gọi trên cùng một đối tượng:

class Counter
  def initialize
    @count = 0
  end

  def add(n)
    @count += n
    self
  end

  def count
    @count
  end
end

puts Counter.new.add(2).add(5).count

Đầu ra:

7

Đối tượng cũng có thể dùng self để chuyển chính nó cho đoạn code khác, chẳng hạn như trả về người chiến thắng khi so sánh với một đối tượng khác cùng lớp:

class Player
  def initialize(name, score)
    @name = name
    @score = score
  end

  def name
    @name
  end

  def score
    @score
  end

  def winner_against(other)
    score >= other.score ? self : other
  end
end

ada = Player.new("Ada", 9)
bo = Player.new("Bo", 7)
puts ada.winner_against(bo).name
puts bo.winner_against(ada).name

Đầu ra:

Ada
Ada

Tên phương thức trả lời câu hỏi có hoặc không kết thúc bằng ?, như empty?. Tham số có thể có giá trị mặc định, được dùng khi bên gọi bỏ qua đối số:

class Kettle
  def initialize
    @temp = 20
  end

  def hot?
    @temp >= 90
  end

  def heat(degrees = 10)
    @temp = [@temp + degrees, 100].min
  end
end

k = Kettle.new
k.heat
puts k.hot?
k.heat(75)
puts k.hot?

Đầu ra:

false
true
challenge icon

Thử thách

Dễ

Hoàn thiện lớp ShoppingCart. add(name, price) lưu một mặt hàng và trả về chính giỏ hàng, nhờ đó bạn có thể nối chuỗi các lệnh gọi. total trả về tổng giá, free_shipping? trả về true khi tổng giá từ 20 trở lên, còn summary trả về 3 items, total 12.50 (hoặc 1 item, total 4.00), với hai chữ số thập phân.

Code được cung cấp thêm một mặt hàng cho mỗi dòng đầu vào (name price) bằng cách nối chuỗi các lệnh gọi, sau đó in ra summary và free shipping: true hoặc free shipping: false.

Viết code của bạn trong shopping_cart.rb. Tệp 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 'shopping_cart'

# Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
input = []
while (line = gets)
  input << line.chomp
end
cart = input.reduce(ShoppingCart.new) do |c, line|
  name, price = line.split
  c.add(name, price.to_f)
end
puts cart.summary
puts "free shipping: #{cart.free_shipping?}"
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch Ruby online