重写方法
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 23 课,共 57 课。
子类可以通过定义一个同名方法来重写该方法。Ruby 会先在对象所属的类中查找方法,只有找不到时才会在父类中查找,因此会使用子类中的版本:
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输出:
Woof
...对于子类对象,调用另一个方法的超类方法会使用被重写的方法。共享的方法只需编写一次,每个子类只需修改不同的部分:
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输出:
Tom says Meow
Thing says ...在子类中重写 to_s,只会改变该子类的打印方式。没有重写的方法仍然来自超类:
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)输出:
Lamp 20.00
Lamp 16.00 (sale)Ruby 搜索的顺序是类的祖先类:先是类本身,然后是它的父类,以此类推,直到 Object。列表中第一个定义了该方法的类会提供这个方法:
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)输出:
Woof
[Puppy, Dog, Animal]挑战
简单完成工资类。Employee 保存一个 name,并有 pay(hours),它会返回 hours * 20;还有 payslip(hours),它会使用 pay 返回 Ada: 800。无论工时是多少,Manager 都会重写 pay,返回固定的 1500。Intern 会重写 pay,返回 hours * 12,但最多为 300。payslip 只在 Employee 中定义。
提供的代码会读取以下行:employee Ada 40、manager Bo 50 或 intern Cy 20,创建匹配的对象并打印工资单,然后打印总工资。
你的代码应写在 employee.rb、manager.rb 和 intern.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'employee'
require_relative 'manager'
require_relative 'intern'
# 提供的输入和输出代码:保持原样
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}"
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器