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: 5Mặ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.
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ớpWallettheo mẫu hàm khởi tạo tiêu chuẩn. Mỗi ví cần theo dõibalanceriê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ư
- Hàm khởi tạo
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:
- Số dư ban đầu của ví A
- Số dư ban đầu của ví B
- Số tiền cần thêm vào ví A
- Số tiền cần chi từ ví B
Trong tệp chính:
- Tạo
walletAvới số dư ban đầu thứ nhất - Tạo
walletBvới số dư ban đầu thứ hai - Thêm số tiền đã cho vào
walletA - Chi số tiền đã cho từ
walletB - 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: 40Lư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]"
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