Kế thừa phương thức
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 32 trên 70.
Khi đã thiết lập quan hệ kế thừa, các đối tượng của lớp con tự động có quyền truy cập vào tất cả phương thức của lớp cha. Điều này diễn ra thông qua chuỗi tra cứu của Lua. Khi bạn gọi một phương thức trên một đối tượng, Lua sẽ tìm kiếm qua từng bảng được liên kết cho đến khi tìm thấy thứ bạn cần.
Hãy xem cách thiết lập này, trong đó Animal định nghĩa phương thức :breathe():
local Animal = {}
Animal.__index = Animal
function Animal:new()
local obj = {}
setmetatable(obj, Animal)
return obj
end
function Animal:breathe()
print("Breathing...")
end
-- Dog kế thừa từ Animal
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new()
local obj = {}
setmetatable(obj, Dog)
return obj
endBây giờ hãy xem điều gì xảy ra khi chúng ta tạo một Dog và gọi phương thức của lớp cha:
local buddy = Dog:new()
buddy:breathe() -- Đầu ra: Breathing...Lớp Dog chưa từng định nghĩa :breathe(), vậy mà nó vẫn hoạt động. Lua kiểm tra buddy trước, không tìm thấy gì, rồi kiểm tra Dog, vẫn không tìm thấy gì, cuối cùng tìm thấy phương thức đó trong Animal. Cơ chế kế thừa phương thức tự động này giúp bạn chỉ cần viết hành vi dùng chung một lần trong lớp cha, rồi mọi lớp con đều được hưởng lợi ngay lập tức.
Thử thách
DễHãy xây dựng một hệ thống phân cấp sinh vật đơn giản để xem cách kế thừa phương thức hoạt động! Bạn sẽ tạo lớp cha Animal và lớp con Dog, sau đó chứng minh rằng các instance của Dog có thể dùng những phương thức chỉ được định nghĩa trong Animal.
Bạn sẽ chia code thành ba tệp:
Animal.lua: Định nghĩa lớp cha theo mẫu lớp tiêu chuẩn. Thêm hàm khởi tạo:new(name)để lưu tên con vật, cùng phương thức:speak()để in tên con vật, theo sau làmakes a sound. Trả về lớp ở cuối tệp.Dog.lua: Định nghĩa lớp con kế thừa từ Animal. Nạp module Animal và thiết lập liên kết kế thừa để Dog có thể truy cập các phương thức của Animal. Thêm hàm khởi tạo:new(name)để lưu tên và đặt Dog làm metatable. Lớp Dog KHÔNG được định nghĩa phương thức:speak()riêng. Lớp này sẽ kế thừa phương thức đó từ Animal.main.lua: Nạp module Dog, đọc tên từ đầu vào, tạo một instance Dog với tên đó và gọi phương thức:speak()trên instance ấy.
Bạn sẽ nhận một đầu vào: tên của chú chó.
Ví dụ, nếu đầu vào là Buddy, đầu ra sẽ là:
Buddy makes a soundĐiều thú vị là lớp Dog không định nghĩa :speak(), nhưng gọi phương thức này trên một instance Dog vẫn hoạt động hoàn hảo. Lua lần theo chuỗi tra cứu từ instance Dog đến lớp Dog, rồi đến lớp Animal, nơi phương thức này được tìm thấy. Đó chính là cách kế thừa hoạt động!
Tự làm thử
-- main.lua: Điểm bắt đầu
local Dog = require('Dog')
-- Đọc tên của chú chó từ đầu vào
local name = io.read()
-- TODO: Tạo một instance Dog với tên đã cho
-- TODO: Gọi phương thức :speak() trên instance Dog
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