Menu
CoddyTech

Ghi đè phương thức

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

Lớp con có thể ghi đè một phương thức bằng cách định nghĩa một phương thức cùng tên. Ruby tìm phương thức trong lớp của chính đối tượng trước, rồi mới tìm trong lớp cha, vì vậy phiên bản trong lớp con sẽ được ưu tiên:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Fish < Animal
end

puts Dog.new.speak
puts Fish.new.speak

Đầu ra:

Woof
...

Một phương thức của lớp cha gọi một phương thức khác sẽ dùng phiên bản đã ghi đè khi làm việc với đối tượng của lớp con. Phương thức dùng chung chỉ cần viết một lần, mỗi lớp con chỉ thay đổi phần khác biệt:

class Animal
  def initialize(name)
    @name = name
  end

  def introduce
    "#{@name} says #{speak}"
  end

  def speak
    "..."
  end
end

class Cat < Animal
  def speak
    "Meow"
  end
end

puts Cat.new("Tom").introduce
puts Animal.new("Thing").introduce

Đầu ra:

Tom says Meow
Thing says ...

Ghi đè to_s trong lớp con sẽ thay đổi cách chỉ lớp con đó in ra. Các phương thức mà lớp con không ghi đè vẫn được kế thừa từ lớp cha:

class Item
  def initialize(name, price)
    @name = name
    @price = price
  end

  def to_s
    format("%s %.2f", @name, @price)
  end
end

class SaleItem < Item
  def to_s
    format("%s %.2f (sale)", @name, @price * 0.8)
  end
end

puts Item.new("Lamp", 20)
puts SaleItem.new("Lamp", 20)

Đầu ra:

Lamp 20.00
Lamp 16.00 (sale)

Thứ tự Ruby tìm kiếm là danh sách lớp tổ tiên của lớp đó: chính lớp đó, rồi đến lớp cha, và cứ tiếp tục như vậy cho đến Object. Lớp đầu tiên trong danh sách định nghĩa phương thức sẽ cung cấp phương thức đó:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Puppy < Dog
end

puts Puppy.new.speak
p Puppy.ancestors.take(3)

Đầu ra:

Woof
[Puppy, Dog, Animal]
challenge icon

Thử thách

Dễ

Hoàn thành các lớp tính lương. Employee lưu name và có pay(hours), trả về hours * 20, cùng với payslip(hours), trả về Ada: 800 bằng cách dùng pay. Manager ghi đè pay bằng mức cố định 1500, bất kể số giờ. Intern ghi đè pay bằng hours * 12, nhưng tối đa là 300. Chỉ Employee định nghĩa payslip.

Code được cung cấp đọc các dòng employee Ada 40, manager Bo 50 hoặc intern Cy 20, tạo đối tượng tương ứng và in phiếu lương của đối tượng đó, sau đó in tổng tiền lương.

Code của bạn nằm trong employee.rb, manager.rb và intern.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 'employee'
require_relative 'manager'
require_relative 'intern'

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "employee" => Employee, "manager" => Manager, "intern" => Intern }
total = 0
input.each do |line|
  kind, name, hours = line.split
  worker = kinds[kind].new(name)
  puts worker.payslip(hours.to_i)
  total += worker.pay(hours.to_i)
end
puts "total: #{total}"
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