Thêm phương thức cho lớp con
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 34 trên 70.
Kế thừa cho phép các lớp con truy cập phương thức của lớp cha, nhưng sức mạnh thực sự đến từ việc thêm phương thức mới chỉ lớp con có. Một Dog có thể làm mọi việc mà Animal làm được, cộng thêm những việc đặc trưng của chó, như sủa.
Thêm một phương thức chỉ dành cho lớp con rất đơn giản: chỉ cần định nghĩa phương thức đó trong bảng lớp con. Vì các đối tượng tìm phương thức trong lớp của mình trước, chúng sẽ tìm thấy phương thức mới mà không ảnh hưởng đến lớp cha.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print(self.name .. " is breathing")
end
-- Dog kế thừa từ Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
-- Phương thức mới chỉ có trong Dog
function Dog:bark()
print(self.name .. " says: Woof!")
endGiờ đây, các đối tượng Dog có thể dùng cả phương thức kế thừa và phương thức riêng:
local buddy = Dog:new("Buddy")
buddy:breathe() -- Đầu ra: Buddy is breathing (kế thừa)
buddy:bark() -- Đầu ra: Buddy says: Woof! (chỉ có ở lớp con)Lớp cha vẫn giữ nguyên: gọi :bark() trên một Animal thông thường sẽ gây lỗi vì phương thức (method) đó không tồn tại ở đó. Đây là cách tính kế thừa (inheritance) cho phép bạn chuyên biệt hóa hành vi mà vẫn giữ các chức năng dùng chung ở một nơi.
Thử thách
DễCùng xây dựng một hệ thống phân cấp thú cưng, trong đó mèo có khả năng đặc biệt riêng! Bạn sẽ tạo lớp cha Pet và lớp con Cat. Cat kế thừa mọi thứ từ Pet, đồng thời có một phương thức riêng mà chỉ mèo mới có thể dùng.
Bạn sẽ sắp xếp code trong ba tệp:
Pet.lua: Định nghĩa lớp cha với hàm khởi tạo:new(name)để lưu tên thú cưng. Thêm phương thức:greet()để in tên thú cưng, theo sau làsays hello. Thiết lập mẫu lớp tiêu chuẩn rồi trả về lớp.Cat.lua: Định nghĩa lớp con kế thừa từ Pet. Hàm khởi tạo:new(name)của Cat nên gọi hàm khởi tạo của lớp cha để khởi tạo tên, sau đó liên kết lại metatable với Cat. Thêm phương thức riêng của lớp con:purr()để in tên mèo, theo sau làpurrs contentedly. Phương thức này chỉ có trong Cat: Pet không có phương thức đó!main.lua: Yêu cầu module Cat, đọc tên từ đầu vào, tạo một instance Cat và minh họa rằng nó có thể dùng cả phương thức kế thừa:greet()lẫn phương thức riêng:purr().
Bạn sẽ nhận một đầu vào: tên của mèo.
Trong tệp chính, tạo một Cat với tên đã cho, rồi lần lượt gọi :greet() và :purr() trên các dòng riêng biệt.
Ví dụ, nếu đầu vào là Whiskers, đầu ra sẽ là:
Whiskers says hello
Whiskers purrs contentedlyDòng đầu tiên xuất phát từ phương thức kế thừa :greet() được định nghĩa trong Pet, còn dòng thứ hai xuất phát từ phương thức :purr() chỉ có trong Cat. Điều này cho thấy lớp con có thể làm mọi việc mà lớp cha làm được, đồng thời có thêm những hành vi chuyên biệt của riêng mình!
Tự làm thử
-- main.lua: Tạo một Cat và minh họa tính kế thừa
local Cat = require('Cat')
-- Đọc tên mèo từ đầu vào
local name = io.read()
-- TODO: Tạo một instance Cat với tên đã cho
-- TODO: Gọi phương thức :greet() kế thừa từ Pet
-- TODO: Gọi phương thức :purr() riêng của Cat
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