Menu
CoddyTech

Kiểm tra tính bằng nhau

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 17 trên 70.

Bạn đã thấy __tostring điều khiển cách một đối tượng hiển thị. Một metamethod hữu ích khác là __eq, dùng để xác định khi nào hai đối tượng được xem là bằng nhau khi dùng toán tử ==.

Theo mặc định, khi so sánh hai bảng bằng ==, chương trình kiểm tra xem chúng có phải là cùng một bảng trong bộ nhớ hay không. Hai đối tượng riêng biệt có dữ liệu giống hệt nhau sẽ trả về false:

local user1 = {id = 101, name = "Alice"}
local user2 = {id = 101, name = "Alice"}
print(user1 == user2)  -- Đầu ra: false (các bảng khác nhau)

Với __eq, bạn có thể định nghĩa logic so sánh bằng của riêng mình. Trong một lớp, bạn thêm nó giống như __tostring, dưới dạng một hàm trong bảng lớp. Để phép so sánh bằng hoạt động, cả hai đối tượng phải dùng chung metatable:

local User = {}
User.__index = User

function User:new(id, name)
    local instance = {}
    setmetatable(instance, self)
    instance.id = id
    instance.name = name
    return instance
end

function User:__eq(other)
    return self.id == other.id
end

Giờ đây, hai đối tượng User được xem là bằng nhau nếu chúng có cùng ID, bất kể các trường khác:

local u1 = User:new(101, "Alice")
local u2 = User:new(101, "Bob")
local u3 = User:new(202, "Alice")

print(u1 == u2)  -- Đầu ra: true (cùng ID)
print(u1 == u3)  -- Đầu ra: false (ID khác nhau)

Mẫu này hữu ích khi các đối tượng đại diện cho những thực thể trong thế giới thực có mã định danh duy nhất: chẳng hạn như khi so sánh các bản ghi trong cơ sở dữ liệu, thực thể trong trò chơi hoặc bất kỳ đối tượng nào mà danh tính quan trọng hơn vị trí trong bộ nhớ.

challenge icon

Thử thách

Dễ

Hãy tạo một lớp Product có thể xác định hai sản phẩm có phải là cùng một mặt hàng hay không, ngay cả khi chúng được lưu trong các bảng hoàn toàn khác nhau! Trong các hệ thống bán lẻ, sản phẩm thường có mã SKU (Stock Keeping Units) duy nhất, và hai sản phẩm được xem là bằng nhau nếu có cùng SKU, bất kể các chi tiết khác như giá có thay đổi hay không.

Bạn sẽ tổ chức code trong hai tệp:

  • Product.lua: Định nghĩa lớp Product theo mẫu prototype tiêu chuẩn. Mỗi sản phẩm cần lưu sku (mã định danh duy nhất) và name. Triển khai phương thức metamethod __eq để hai sản phẩm được xem là bằng nhau khi chúng có cùng SKU: tên không ảnh hưởng đến việc so sánh bằng.
  • main.lua: Yêu cầu module Product và tạo một số instance sản phẩm. So sánh chúng bằng toán tử == để xem logic so sánh bằng tùy chỉnh hoạt động.

Lớp Product cần có:

  • Hàm khởi tạo :new(sku, name)
  • Phương thức :getInfo() trả về một chuỗi theo định dạng: [sku]: [name]
  • Phương thức metamethod __eq so sánh sản phẩm dựa trên SKU

Bạn sẽ nhận được sáu đầu vào:

  1. SKU của sản phẩm thứ nhất
  2. Tên của sản phẩm thứ nhất
  3. SKU của sản phẩm thứ hai
  4. Tên của sản phẩm thứ hai
  5. SKU của sản phẩm thứ ba
  6. Tên của sản phẩm thứ ba

Trong tệp chính, hãy tạo ba sản phẩm bằng các đầu vào đã cho, sau đó in ra:

  1. Thông tin của từng sản phẩm (ba dòng)
  2. Kết quả so sánh sản phẩm 1 với sản phẩm 2
  3. Kết quả so sánh sản phẩm 1 với sản phẩm 3

Ví dụ, nếu các đầu vào là ABC123, Wireless Mouse, ABC123, Mouse (Updated), XYZ789 và Keyboard, đầu ra sẽ là:

ABC123: Wireless Mouse
ABC123: Mouse (Updated)
XYZ789: Keyboard
true
false

Hãy chú ý rằng hai sản phẩm đầu tiên bằng nhau (cùng SKU), dù tên của chúng khác nhau. Đây chính là cách các hệ thống quản lý hàng tồn kho thực tế theo dõi sản phẩm khi tên thay đổi và được cập nhật!

Tự làm thử

-- Nạp module Product
local Product = require('Product')

-- Đọc dữ liệu đầu vào
local sku1 = io.read()
local name1 = io.read()
local sku2 = io.read()
local name2 = io.read()
local sku3 = io.read()
local name3 = io.read()

-- TODO: Tạo ba instance Product từ dữ liệu đầu vào

-- TODO: In ra thông tin của từng sản phẩm (ba dòng)

-- TODO: In ra kết quả so sánh sản phẩm 1 với sản phẩm 2

-- TODO: In ra kết quả so sánh sản phẩm 1 với sản phẩm 3
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 Lua online