Menu
CoddyTech

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
end

Bâ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.

challenge icon

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
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch Lua online