Trừ các đối tượng
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 27 trên 70.
Giống như __add xử lý toán tử +, phương thức đặc biệt __sub xác định cách hoạt động của toán tử -. Cách làm hoàn toàn giống nhau. Bạn định nghĩa một hàm nhận hai toán hạng và trả về một đối tượng mới.
local Color = {}
Color.__index = Color
function Color:new(r, g, b)
local obj = {r = r, g = g, b = b}
setmetatable(obj, Color)
return obj
end
function Color.__sub(c1, c2)
return Color:new(c1.r - c2.r, c1.g - c2.g, c1.b - c2.b)
endKhi làm việc với màu RGB, phép trừ có thể tạo ra giá trị âm. Trong các ứng dụng thực tế, bạn có thể muốn giới hạn kết quả trong phạm vi hợp lệ (0-255), nhưng cấu trúc metamethod cốt lõi vẫn giữ nguyên.
local bright = Color:new(200, 150, 100)
local dim = Color:new(50, 30, 20)
local result = bright - dim
print(result.r, result.g, result.b) -- Đầu ra: 150 120 80Hãy nhớ: định nghĩa __sub bằng dấu chấm (không phải dấu hai chấm), vì đây là metamethod mà Lua gọi trực tiếp với cả hai toán hạng làm đối số.
Thử thách
DễHãy xây dựng một lớp Color hỗ trợ phép trừ bằng toán tử -. Màu sắc được biểu diễn bằng các giá trị RGB, phép trừ một màu cho màu khác sẽ tạo ra màu mới với hiệu của từng thành phần.
Bạn sẽ chia code thành hai tệp:
Color.lua: Định nghĩa lớp Color với các thành phầnr,gvàb, lần lượt biểu thị giá trị đỏ, xanh lá và xanh dương. Thêm hàm khởi tạo:new(r, g, b)và triển khai metamethod__subđể phép trừ hai màu tạo ra màu mới với hiệu của từng thành phần. Hãy nhớ rằng__subdùng cú pháp dấu chấm và nhận cả hai toán hạng làm đối số.main.lua: Nạp module Color, tạo các instance màu từ đầu vào đã cho, trừ chúng cho nhau và hiển thị các giá trị RGB của màu kết quả.
Bạn sẽ nhận sáu đầu vào:
- Thành phần đỏ của màu thứ nhất
- Thành phần xanh lá của màu thứ nhất
- Thành phần xanh dương của màu thứ nhất
- Thành phần đỏ của màu thứ hai
- Thành phần xanh lá của màu thứ hai
- Thành phần xanh dương của màu thứ hai
Trong tệp chính, hãy tạo hai màu với các giá trị RGB đã cho, trừ màu thứ hai cho màu thứ nhất bằng toán tử -, rồi in các giá trị r, g và b của màu kết quả trên các dòng riêng biệt.
Ví dụ, nếu đầu vào là 200, 150, 100, 50, 30, 20, đầu ra sẽ là:
150
120
80Màu thứ nhất (200, 150, 100) trừ màu thứ hai (50, 30, 20) bằng màu mới (150, 120, 80).
Tự làm thử
-- Nạp module Color
local Color = require('Color')
-- Đọc các giá trị đầu vào
local r1 = tonumber(io.read())
local g1 = tonumber(io.read())
local b1 = tonumber(io.read())
local r2 = tonumber(io.read())
local g2 = tonumber(io.read())
local b2 = tonumber(io.read())
-- TODO: Tạo hai instance Color với các giá trị RGB đã cho
-- TODO: Dùng toán tử - để lấy màu thứ nhất trừ màu thứ hai
-- TODO: In các giá trị r, g và b của màu kết quả, mỗi giá trị trên một dòng riêng
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