0Pricing
Lua Academy · บทเรียน

การสืบทอดเดี่ยวด้วยการเชื่อมโยง __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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสืบทอดเดี่ยวด้วยการเชื่อมโยง __index
  2. การเรียกเมธอดของคลาสแม่ด้วย super
  3. รูปแบบมิกซิน
  4. การเขียนทับและพหุรูป
← กลับไปที่ Lua Academy