การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index
กำหนดคลาสแม่เป็น __index ของเมทาเทเบิลเพื่อสืบทอดเมธอด
การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
สายโซ่ต้นแบบ
การสืบทอดเดี่ยวทำงานโดยกำหนด __index ของคลาสลูกให้ชี้ไปยังคลาสแม่ เมื่อไม่พบเมธอดในคลาสลูก Lua จะค้นหาในคลาสแม่ ทำให้เกิดสายโซ่ต้นแบบ
local Base={}
Base.__index=Base
function Base.new() return setmetatable({},Base) end
function Base:greet() print("Hello from Base") end
local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base}) -- Child inherits Base
function Child.new() return setmetatable({},Child) end
local c=Child.new()
c:greet() -- Hello from Base (inherited)ลำดับการค้นหาเมธอด
เมื่อเรียกเมธอดบนอินสแตนซ์: (1) ค้นหาในตารางอินสแตนซ์ (2) ค้นหาใน Child (ผ่าน __index) (3) ค้นหาใน Base (ผ่าน __index ในเมตาเทเบิลของ Child) ระบบจะใช้รายการแรกที่พบ
local Base={}
Base.__index=Base
function Base:who() print("I am Base") end
local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:who() print("I am Child") end -- override
local b=setmetatable({},Base)
local c=setmetatable({},Child)
b:who() -- I am Base
c:who() -- I am Child (overrides)การสืบทอดตัวสร้าง
คลาสลูกสามารถใช้ตัวสร้างของคลาสแม่ซ้ำได้โดยเรียกตัวสร้างนั้น หรือกำหนดตัวสร้างของตนเองเพื่อเพิ่มขั้นตอนต่อจากการเริ่มต้นของคลาสแม่
local Animal={}
Animal.__index=Animal
function Animal.new(name,sound)
return setmetatable({name=name,sound=sound},Animal)
end
function Animal:speak() print(self.name..": "..self.sound) end
local Dog={}
Dog.__index=Dog
setmetatable(Dog,{__index=Animal})
function Dog.new(name)
local self = Animal.new(name,"Woof")
return setmetatable(self,Dog)
end
function Dog:fetch(item) print(self.name.." fetches "..item) end
local d=Dog.new("Rex")
d:speak(); d:fetch("ball")การตรวจสอบบรรพบุรุษ
ไล่ขึ้นไปตามสายโซ่เมตาเทเบิลเพื่อตรวจสอบว่าคลาสของวัตถุสืบทอดจากคลาสพื้นฐานที่กำหนดหรือไม่ นี่คือวิธีที่ instanceof ทำงานใน Lua
local function instanceof(obj, cls)
local mt = getmetatable(obj)
while mt do
if mt == cls then return true end
mt = getmetatable(mt)
end
return false
endการเรียกคลาสแม่
เรียกเมธอดเวอร์ชันของคลาสแม่ที่ถูกเขียนทับโดยเข้าถึงเมธอดนั้นโดยตรงผ่านตารางคลาสแม่
local Base={}
Base.__index=Base
function Base:init(x) self.x=x end
function Base:value() return self.x end
local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
function Child:init(x,y)
Base.init(self,x) -- call parent
self.y=y
end
function Child:value() return Base.value(self)+self.y end
local c=setmetatable({},Child)
c:init(3,4)
print(c:value()) -- 7สายโซ่ลึก
สร้างลำดับชั้นสามระดับ: A → B → C การค้นหาเมธอดจะเดินผ่านสายโซ่ทั้งหมดจนกว่าจะพบเมธอด
local A={}
A.__index=A
function A:aMethod() print("A method") end
local B={}
B.__index=B
setmetatable(B,{__index=A})
function B:bMethod() print("B method") end
local C={}
C.__index=C
setmetatable(C,{__index=B})
local c=setmetatable({},C)
c:bMethod() -- from B
c:aMethod() -- from Aการเขียนทับฟิลด์
อินสแตนซ์สามารถเขียนทับฟิลด์ระดับคลาสได้โดยกำหนดค่าให้ฟิลด์นั้นโดยตรง ฟิลด์ของคลาสจะไม่เปลี่ยนแปลง แต่จะถูกบดบังเฉพาะสำหรับอินสแตนซ์นั้น
local Creature={}
Creature.__index=Creature
Creature.hp=100
Creature.speed=10
function Creature.new()
return setmetatable({},Creature)
end
local fast=Creature.new()
fast.speed=20 -- override for this instance
local normal=Creature.new()
print(fast.speed,normal.speed,Creature.speed) -- 20 10 10การสืบทอดระดับคลาส
การกำหนด setmetatable(Child, {__index=Parent}) ทำให้การค้นหาระดับคลาสส่งต่อไปยังคลาสแม่เมื่อไม่พบค่าในคลาสลูก นั่นหมายความว่า Child.classMethod() จะพบเมธอดในคลาสแม่หากไม่มีการเขียนทับ
local Vehicle={}
Vehicle.__index=Vehicle
Vehicle.maxSpeed=120
function Vehicle.describe() print("Vehicle") end
local Car={}
Car.__index=Car
setmetatable(Car,{__index=Vehicle})
Car.describe() -- Vehicle (inherited class method)
print(Car.maxSpeed) -- 120 (inherited class field)สายโซ่การเริ่มต้น
เพื่อให้เริ่มต้นได้อย่างถูกต้อง ตัวสร้างของคลาสลูกต้องเรียกตัวสร้างของคลาสแม่ เพื่อให้แน่ใจว่าสถานะของคลาสแม่ได้รับการตั้งค่าแล้ว ให้การเริ่มต้นทำงานต่อเนื่องขึ้นไปตามลำดับชั้น
local Base={}
Base.__index=Base
function Base:_init(name) self.name=name end
local Mid={}
Mid.__index=Mid
setmetatable(Mid,{__index=Base})
function Mid:_init(name,level)
Base._init(self,name)
self.level=level
end
local Top={}
Top.__index=Top
setmetatable(Top,{__index=Mid})
function Top.new(name,level,role)
local self=setmetatable({},Top)
Mid._init(self,name,level)
self.role=role
return self
end
local t=Top.new("Alice",5,"admin")
print(t.name,t.level,t.role)คลาสพื้นฐานนามธรรม
สร้างคลาสพื้นฐานที่มีเมธอดซึ่งยังไม่ได้เขียนการทำงานและจะทำให้เกิดข้อผิดพลาด คลาสย่อยต้องเขียนทับเมธอดเหล่านี้ วิธีนี้บังคับใช้ข้อตกลงของอินเทอร์เฟซในระบบชนิดข้อมูลแบบพลวัตของ Lua
local Serializer={}
Serializer.__index=Serializer
function Serializer:encode(data)
error(self._type.." must implement encode()",2)
end
function Serializer:decode(str)
error(self._type.." must implement decode()",2)
end
local JSONSerializer={_type="JSON"}
setmetatable(JSONSerializer,{__index=Serializer})
function JSONSerializer:encode(data)
return "{"..tostring(data.key).."}"
end
local j=setmetatable({_type="JSON"},JSONSerializer)
print(j:encode({key="val"}))คำถามเรื่องการสืบทอด
อะไรทำให้ Lua รองรับการสืบทอดเดี่ยว
สรุป: การสืบทอดเดี่ยว
กำหนด setmetatable(Child, {__index = Parent}) เพื่อสืบทอดเมธอด สายโซ่ __index จะมอบหมายงานต่อโดยอัตโนมัติ หากต้องการเขียนทับ ให้กำหนดเมธอดใน Child และเรียกคลาสแม่โดยตรงด้วย Parent.method(self)
คำถามที่พบบ่อย
บทเรียน “การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index”
กำหนดคลาสแม่เป็น __index ของเมทาเทเบิลเพื่อสืบทอดเมธอด คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม
ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index
- การเรียกเมธอดของคลาสแม่ด้วย super
- รูปแบบมิกซิน
- การเขียนทับและพหุรูป