Dấu chấm và dấu hai chấm
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 4 trên 70.
Giờ bạn đã biết cả cú pháp dấu chấm và dấu hai chấm, hãy cùng tìm hiểu mối liên hệ giữa chúng và điều gì xảy ra khi không truyền bảng.
Cả hai dấu hai chấm đều là dạng viết tắt. Định nghĩa function game:addPoints(points) giống với định nghĩa function game.addPoints(self, points), và gọi game:addPoints(10) giống với gọi game.addPoints(game, 10). Phương thức hoạt động miễn là bảng được truyền vào làm đối số đầu tiên.
Đây là điều xảy ra khi bảng không được truyền vào:
local game = { score = 0 }
function game:addPoints(points)
self.score = self.score + points
end
-- SAI: gọi bằng dấu chấm nhưng không truyền bảng vào
game.addPoints(10) -- Lỗi! self giờ là 10, không phải bảngKhi bạn gọi game.addPoints(10), Lua không tự động truyền game. Giá trị 10 trở thành self, và self.score gây lỗi vì 10 là một số, không phải một bảng.
Một hàm được định nghĩa bằng dấu chấm và có tham số self tường minh sẽ hoạt động với cách gọi bằng dấu hai chấm, vì dấu hai chấm truyền bảng làm đối số đầu tiên:
function game.reset(self)
self.score = 0
end
-- Gọi bằng dấu hai chấm: game:reset() tương đương với game.reset(game)
game:reset() -- self nhận đúng game nên cách này hoạt độngCả hai cách định nghĩa đều tạo ra cùng một hàm, nên lựa chọn này phụ thuộc vào quy ước: dùng dấu hai chấm để định nghĩa và gọi các hàm hoạt động trên self, còn dùng dấu chấm cho các hàm không dùng self. Như vậy, mỗi lần gọi đều cho thấy liệu bảng có được truyền vào hay không.
Thử thách
DễTạo một bảng tên player có trường score được khởi tạo bằng 0.
Thêm hai hàm vào bảng:
player.setScore(self, value)- được định nghĩa bằng cú pháp dấu chấm và có tham sốselftường minh. Gán giá trị đã cho choself.score.player:addBonus(amount)- được định nghĩa bằng cú pháp dấu hai chấm. Cộngamountvàoself.score.
Bạn sẽ nhận được hai đầu vào:
- Giá trị điểm ban đầu
- Lượng điểm thưởng cần cộng thêm
Thực hiện các bước sau:
- Gọi
setScorebằng cú pháp dấu chấm (truyền bảng làm đối số đầu tiên) để đặt điểm ban đầu - Gọi
addBonusbằng cú pháp dấu hai chấm để cộng điểm thưởng - In ra giá trị cuối cùng của
player.score
Hãy nhớ: cách bạn gọi mỗi hàm phải khớp với cách hàm đó được định nghĩa.
Tự làm thử
-- Đọc đầu vào
local initialScore = tonumber(io.read())
local bonusAmount = tonumber(io.read())
-- TODO: Viết code của bạn bên dưới
-- 1. Tạo bảng tên 'player' có trường 'score' được khởi tạo bằng 0
-- 2. Thêm player.setScore(self, value) bằng cú pháp dấu chấm, ghi rõ self
-- 3. Thêm player:addBonus(amount) bằng cú pháp dấu hai chấm
-- 4. Gọi setScore bằng cú pháp dấu chấm (truyền bảng làm đối số đầu tiên)
-- 5. Gọi addBonus bằng cú pháp dấu hai chấm
-- In ra điểm cuối cùng
print(player.score)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