So sánh các đối tượng (<, >)
Thuộc phần Lập trình hướng đối tượng trong hành trình Lua của Coddy. Bài học 29 trên 70.
Ngoài phép tính số học và phép nối chuỗi, bạn cũng có thể định nghĩa cách các đối tượng so sánh với nhau bằng các metamethod so sánh. Metamethod __lt xử lý toán tử “nhỏ hơn” (<).
Khi Lua đánh giá a < b, Lua tìm __lt trong metatable. Phương thức biến đổi này nên trả về true hoặc false dựa trên logic so sánh của bạn.
local Item = {}
Item.__index = Item
function Item:new(name, price)
local obj = {name = name, price = price}
setmetatable(obj, Item)
return obj
end
function Item.__lt(a, b)
return a.price < b.price
endKhi đã định nghĩa __lt, giờ bạn có thể so sánh trực tiếp các mục:
local apple = Item:new("Apple", 2)
local laptop = Item:new("Laptop", 999)
print(apple < laptop) -- Đầu ra: true
print(laptop < apple) -- Đầu ra: falseĐây là điểm thú vị: Lua tự động suy ra toán tử > từ __lt. Khi bạn viết a > b, Lua chỉ cần tính b < a. Vì vậy, chỉ cần định nghĩa __lt là bạn đã có cả hai chiều so sánh.
Thử thách
DễHãy tạo một lớp Product có thể được so sánh bằng toán tử < và > dựa trên giá. Cách này rất phù hợp với những tình huống như sắp xếp các mặt hàng trong giỏ hàng hoặc tìm lựa chọn rẻ nhất trong một danh sách.
Bạn sẽ sắp xếp code thành hai tệp:
Product.lua: Định nghĩa lớp Product với các trườngnamevàprice. Thêm hàm khởi tạo:new(name, price)và triển khai phương thức metamethod__ltđể so sánh các sản phẩm theo giá. Hãy nhớ rằng khi định nghĩa__lt, bạn cũng tự động có toán tử>: Lua sẽ xử lý việc đó cho bạn!main.lua: Nạp module Product, tạo các instance sản phẩm từ đầu vào và so sánh chúng để xác định sản phẩm nào đắt hơn hoặc rẻ hơn.
Bạn sẽ nhận được bốn đầu vào:
- Tên sản phẩm thứ nhất
- Giá sản phẩm thứ nhất
- Tên sản phẩm thứ hai
- Giá sản phẩm thứ hai
Trong tệp chính, hãy tạo hai sản phẩm với tên và giá đã cho. Sau đó thực hiện ba phép so sánh và in kết quả của từng phép trên một dòng riêng:
- Sản phẩm thứ nhất có giá thấp hơn sản phẩm thứ hai không? (in
truehoặcfalse) - Sản phẩm thứ nhất có giá cao hơn sản phẩm thứ hai không? (in
truehoặcfalse) - In tên sản phẩm rẻ hơn
Ví dụ, nếu đầu vào là Apple, 2, Laptop và 999, đầu ra sẽ là:
true
false
AppleApple (giá 2) có giá thấp hơn Laptop (giá 999), vì vậy kết quả so sánh thứ nhất là true. Apple không có giá cao hơn Laptop, nên kết quả thứ hai là false. Vì Apple có giá thấp hơn, tên sản phẩm này sẽ được in ra là sản phẩm rẻ hơn.
Tự làm thử
-- Nạp module Product
local Product = require('Product')
-- Đọc các giá trị đầu vào
local name1 = io.read()
local price1 = tonumber(io.read())
local name2 = io.read()
local price2 = tonumber(io.read())
-- TODO: Tạo hai instance Product bằng Product:new()
-- TODO: So sánh các sản phẩm bằng toán tử < và in ra true/false
-- TODO: So sánh các sản phẩm bằng toán tử > và in ra true/false
-- TODO: In ra tên sản phẩm rẻ hơn
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
1Khái niệm “self”
Bảng với hàm“self” tường minhCú pháp dấu hai chấmDấu chấm và dấu hai chấmÔn tập: Điểm chuyển động4Dự án: Ngân hàng số
Thiết lập dự ánPhương thức nạp tiền2Mẫu Prototype cho lớp
Khái niệm PrototypeLiên kết bằng __indexHàm khởi tạo :new()Khởi tạo thuộc tínhCác instance độc lậpÔn tập: Nhà máy ô tô5Nạp chồng toán tử trong OOP
Cộng các đối tượngTrừ các đối tượngNối các đối tượngSo sánh các đối tượng (<, >)Ôn tập: phép tính với ví tiền8Đóng gói
Quy ước đặt tênClosure để bảo mậtTruy cập qua closureBảng chỉ đọcLogic kiểm tra hợp lệTổng kết: Két an toàn11Mẫu thiết kế (cơ bản)
Hàm tạo đối tượngBảng SingletonMẫu IteratorObserver (Listener)Ôn tập: Factory Logger3Trạng thái và hành vi của đối tượng
Biến instancePhương thức getterPhương thức setterThuộc tính tính toánĐịnh dạng chuỗiKiểm tra tính bằng nhauÔn tập: điểm số học sinh6Cơ bản về kế thừa
Thiết lập kế thừaKế thừa phương thứcMở rộng hàm khởi tạoThêm phương thức cho lớp conDùng chung và riêngÔn tập: hệ phân cấp hình dạngTự luyện tập: Trình biên dịch Lua online