Phương thức toán 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 38 trên 57.
Hầu hết toán tử trong Ruby đều là phương thức. a + b gọi a.+(b), vì vậy một lớp định nghĩa + như mọi phương thức khác. Phép tính số học trên các đối tượng giá trị trả về một đối tượng mới và giữ nguyên cả hai toán hạng:
class Vector
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def +(other)
Vector.new(x + other.x, y + other.y)
end
def to_s
"(#{x}, #{y})"
end
end
a = Vector.new(1, 2)
b = Vector.new(3, 4)
puts a + b
puts aĐầu ra:
(4, 6)
(1, 2)Toán hạng bên phải có thể là một kiểu giá trị khác, chẳng hạn như một số dùng để nhân tỷ lệ. Phép trừ một ngôi là phương thức -@:
class Vector
attr_reader :x, :y
def initialize(x, y)
@x = x
@y = y
end
def -(other)
Vector.new(x - other.x, y - other.y)
end
def *(factor)
Vector.new(x * factor, y * factor)
end
def -@
Vector.new(-x, -y)
end
def to_s
"(#{x}, #{y})"
end
end
v = Vector.new(3, 4)
puts v * 2
puts v - Vector.new(1, 1)
puts(-v)Đầu ra:
(6, 8)
(2, 3)
(-3, -4)Khi đã có +, += cũng hoạt động, vì a += b có nghĩa là a = a + b. sum cũng hoạt động khi bạn cung cấp giá trị khởi đầu thuộc lớp của mình:
class Money
attr_reader :cents
def initialize(cents)
@cents = cents
end
def +(other)
Money.new(cents + other.cents)
end
def to_s
format("$%.2f", cents / 100.0)
end
end
total = Money.new(0)
total += Money.new(250)
total += Money.new(199)
puts total
puts [Money.new(100), Money.new(5)].sum(Money.new(0))Đầu ra:
$4.49
$1.05<=> cũng là một toán tử. Kết hợp với Comparable, nó cho phép so sánh và sắp xếp các đối tượng Money, còn toán tử có thể từ chối một toán hạng không khớp bằng cách phát sinh lỗi, giống như với các số:
class Money
include Comparable
attr_reader :cents, :currency
def initialize(cents, currency)
@cents = cents
@currency = currency
end
def +(other)
raise ArgumentError, "cannot add #{other.currency} to #{currency}" unless other.currency == currency
Money.new(cents + other.cents, currency)
end
def <=>(other)
cents <=> other.cents
end
end
puts Money.new(500, "EUR") > Money.new(300, "EUR")
begin
Money.new(1, "EUR") + Money.new(1, "USD")
rescue ArgumentError => e
puts e.message
endĐầu ra:
true
cannot add USD to EURThử thách
DễHoàn thiện lớp Vector. Định nghĩa các toán tử + và - cho hai vector, * cho một vector và một số, dấu trừ một ngôi -@, == để so sánh cả hai tọa độ, và to_s, hàm này trả về (4, 6). length trả về độ dài của vector bằng Math.sqrt.
Code được cung cấp đọc các biểu thức: 1,2 + 3,4, 1,2 - 3,4, 1,2 * 3, neg 1,2 và 1,2 == 1,2. Code in ra kết quả của từng biểu thức, và với kết quả là vector, còn in ra length 7.21 với hai chữ số thập phân.
Phần code của bạn nằm trong vector.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 'vector'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
input << line.chomp
end
def vec(text)
Vector.new(*text.split(",").map(&:to_i))
end
input.each do |line|
parts = line.split
result = if parts[0] == "neg" then -vec(parts[1])
else
a = vec(parts[0])
case parts[1]
when "+" then a + vec(parts[2])
when "-" then a - vec(parts[2])
when "*" then a * parts[2].to_i
else a == vec(parts[2])
end
end
puts result
puts format("length %.2f", result.length) if result.is_a?(Vector)
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ệ8Phương thức đặc biệt
Tính bằng nhau và hashPhương thức toán tửTruy cập theo chỉ số và thêm phần tửBộ sưu tập tùy chỉnhÔn tập: phân sốTự luyện tập: Trình biên dịch Ruby online