Menu
CoddyTech

Biến instance

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

Chào mừng bạn đến với chương mới, tập trung vào cách các đối tượng quản lý dữ liệu bên trong. Bạn đã học cách tạo lớp và các instance. Bây giờ là lúc khám phá cách mỗi instance lưu trữ và quản lý trạng thái riêng của mình.

Biến thực thể là các trường chỉ thuộc về một đối tượng duy nhất. Khi bạn gán giá trị cho self.something bên trong một phương thức hoặc hàm khởi tạo, dữ liệu đó chỉ tồn tại trong thực thể cụ thể ấy. Các đối tượng khác cùng lớp có bản sao riêng.

Điều này đặc biệt quan trọng khi lưu trữ dữ liệu phức tạp như các bảng. Hãy xem xét một hệ thống kho hàng, trong đó mỗi nhân vật mang theo những vật phẩm khác nhau:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- Mỗi instance có một bảng rỗng riêng
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

Dòng then chốt là instance.items = {}. Khi tạo một bảng mới, trống, bên trong hàm khởi tạo, mỗi đối tượng kho đồ sẽ có danh sách riêng. Nếu thay vào đó bạn định nghĩa items ngay trong bảng lớp, tất cả các đối tượng sẽ vô tình dùng chung một bảng: thêm một thanh kiếm vào kho của một nhân vật sẽ khiến mọi người đều có nó!

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- Đầu ra: 1
print(#bag2.items)  -- Đầu ra: 1

Mỗi kho hàng có bộ sưu tập riêng. Mẫu này áp dụng khi một đối tượng cần theo dõi dữ liệu thay đổi độc lập, chẳng hạn như danh sách, bộ đếm hoặc trạng thái có thể thay đổi chỉ thuộc về đối tượng đó.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống ShoppingCart, trong đó mỗi giỏ hàng có danh sách sản phẩm riêng. Qua đó, bạn sẽ thấy cách biến của từng đối tượng giúp dữ liệu giữa các đối tượng không bị lẫn lộn: thêm sản phẩm vào giỏ này sẽ không ảnh hưởng đến giỏ khác!

Bạn sẽ sắp xếp code trong hai tệp:

  • ShoppingCart.lua: Định nghĩa lớp ShoppingCart, trong đó mỗi đối tượng có bảng products riêng. Hãy thêm:
    • Hàm khởi tạo :new() để tạo danh sách sản phẩm trống cho mỗi giỏ hàng
    • Phương thức :addProduct(productName) để thêm sản phẩm vào danh sách của giỏ hàng này
    • Phương thức :listProducts() để in từng sản phẩm trên một dòng riêng
  • main.lua: Nạp module ShoppingCart và tạo hai giỏ hàng riêng. Thêm các sản phẩm khác nhau vào mỗi giỏ để chứng minh rằng chúng duy trì danh mục hàng hóa độc lập.

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

  1. Sản phẩm đầu tiên cần thêm vào giỏ A
  2. Sản phẩm thứ hai cần thêm vào giỏ A
  3. Sản phẩm đầu tiên cần thêm vào giỏ B
  4. Sản phẩm thứ hai cần thêm vào giỏ B

Trong tệp chính:

  1. Tạo hai giỏ hàng: cartA và cartB
  2. Thêm hai sản phẩm đầu tiên vào cartA
  3. Thêm hai sản phẩm cuối cùng vào cartB
  4. In Cart A:, sau đó liệt kê các sản phẩm trong giỏ A
  5. In Cart B:, sau đó liệt kê các sản phẩm trong giỏ B

Ví dụ, nếu đầu vào là Apple, Bread, Milk và Eggs, đầu ra sẽ là:

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

Hãy nhớ: điều quan trọng là khởi tạo products thành một bảng trống mới bên trong hàm khởi tạo. Như vậy, mỗi đối tượng giỏ hàng sẽ có danh sách riêng thay vì dùng chung một bảng cho tất cả các giỏ.

Tự làm thử

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

-- Đọc các giá trị đầu vào
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: Tạo hai giỏ hàng: cartA và cartB

-- TODO: Thêm product1 và product2 vào cartA

-- TODO: Thêm product3 và product4 vào cartB

-- TODO: In ra "Cart A:", rồi liệt kê các sản phẩm trong cartA

-- TODO: In ra "Cart B:", rồi liệt kê các sản phẩm trong cartB
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