Menu
CoddyTech

Các instance độc lập

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

Một khía cạnh quan trọng của lập trình hướng đối tượng là mỗi đối tượng có trạng thái riêng. Khi bạn tạo hai đối tượng từ cùng một lớp, chúng hoàn toàn độc lập: thay đổi đối tượng này không ảnh hưởng đến đối tượng kia.

Hãy xem ví dụ này:

local Counter = {}
Counter.__index = Counter

function Counter:new(start)
    local instance = {}
    setmetatable(instance, self)
    instance.value = start or 0
    return instance
end

function Counter:increment()
    self.value = self.value + 1
end

-- Tạo hai bộ đếm riêng biệt
local counterA = Counter:new(10)
local counterB = Counter:new(5)

counterA:increment()
counterA:increment()

print(counterA.value)  -- Đầu ra: 12
print(counterB.value)  -- Đầu ra: 5

Mặc dù cả hai bộ đếm đều thuộc cùng một lớp Counter, việc tăng counterA không ảnh hưởng đến counterB. Mỗi đối tượng có trường value riêng được lưu trong bảng instance riêng.

Chính sự độc lập này khiến các đối tượng trở nên hữu ích. Bạn có thể tạo hàng chục nhân vật trong một trò chơi, mỗi nhân vật theo dõi sức khỏe và điểm số riêng. Bạn có thể quản lý nhiều tài khoản ngân hàng, mỗi tài khoản có số dư khác nhau.

Lớp xác định cấu trúc và hành vi, nhưng mỗi đối tượng có dữ liệu riêng và hoạt động độc lập.

challenge icon

Thử thách

Dễ

Hãy chứng minh rằng các đối tượng thuộc cùng một lớp thực sự hoạt động độc lập! Bạn sẽ tạo lớp Wallet và hai instance ví riêng biệt, sau đó sửa đổi từng ví độc lập để chứng minh thay đổi ở ví này không ảnh hưởng đến ví kia.

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

  • Wallet.lua: Định nghĩa lớp Wallet theo mẫu hàm khởi tạo tiêu chuẩn. Mỗi ví cần theo dõi balance riêng. Bao gồm:
    • Hàm khởi tạo :new(startingBalance) để khởi tạo ví với số tiền đã cho
    • Phương thức :add(amount) để tăng số dư
    • Phương thức :spend(amount) để giảm số dư
  • main.lua: Dùng require để tải module Wallet và tạo hai instance ví riêng biệt. Thực hiện các thao tác khác nhau trên từng ví để cho thấy chúng duy trì trạng thái độc lập.

Bạn sẽ nhận bốn giá trị đầu vào:

  1. Số dư ban đầu của ví A
  2. Số dư ban đầu của ví B
  3. Số tiền cần thêm vào ví A
  4. Số tiền cần chi từ ví B

Trong tệp chính:

  1. Tạo walletA với số dư ban đầu thứ nhất
  2. Tạo walletB với số dư ban đầu thứ hai
  3. Thêm số tiền đã cho vào walletA
  4. Chi số tiền đã cho từ walletB
  5. In hai số dư ra các dòng riêng biệt

In số dư cuối cùng theo đúng định dạng sau:

Wallet A: [balance]
Wallet B: [balance]

Ví dụ, nếu đầu vào là 100, 50, 25 và 10, đầu ra sẽ là:

Wallet A: 125
Wallet B: 40

Lưu ý rằng việc thêm tiền vào ví A không làm thay đổi ví B, còn việc chi tiền từ ví B không ảnh hưởng đến ví A: mỗi instance duy trì số dư riêng.

Tự làm thử

-- Nạp module Wallet bằng require
local Wallet = require('Wallet')

-- Đọc các giá trị đầu vào
local startingA = tonumber(io.read())
local startingB = tonumber(io.read())
local addAmount = tonumber(io.read())
local spendAmount = tonumber(io.read())

-- TODO: Tạo walletA với số dư ban đầu thứ nhất

-- TODO: Tạo walletB với số dư ban đầu thứ hai

-- TODO: Thêm số tiền đã chỉ định vào walletA

-- TODO: Chi số tiền đã chỉ định từ walletB

-- TODO: In ra số dư cuối cùng theo định dạng yêu cầu
-- Định dạng: "Wallet A: [balance]" và "Wallet B: [balance]"
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