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

การเรียกเมธอดของคลาสแม่ด้วย super

เรียกเมธอดของคลาสฐานอย่างชัดเจนเพื่อการกำหนดค่าเริ่มต้นแบบทำงานร่วมกัน

การเรียกเมธอดของคลาสแม่ด้วย super เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องเรียกคลาสแม่

เมื่อคลาสลูกเขียนทับเมธอดของคลาสแม่ แต่ยังต้องใช้ตรรกะของคลาสแม่ คลาสลูกจะเรียกเมธอดของคลาสแม่โดยตรง Lua ไม่มีคีย์เวิร์ด super จึงต้องอ้างอิงตารางของคลาสแม่โดยตรง: Parent.method(self, args)

local Base={}
Base.__index=Base
function Base:describe()
  return "Base[name="..self.name.."]"
end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})

function Child:describe()
  local parentDesc = Base.describe(self)  -- super call
  return parentDesc .. " + Child[extra=true]"
end

local c=setmetatable({name="X"},Child)
print(c:describe())

การเรียกคลาสแม่ในตัวสร้าง

ตัวสร้างของคลาสลูกเรียกตัวสร้างของคลาสแม่ผ่าน Parent.new() หรือ Parent._init(self,...) เพื่อให้แน่ใจว่าการเริ่มต้นของคลาสแม่ทำงานกับอินสแตนซ์ลูกทุกตัว

local Animal={}
Animal.__index=Animal
function Animal._init(self,name,sound)
  self.name=name; self.sound=sound; self.alive=true
end

local Dog={}
Dog.__index=Dog; setmetatable(Dog,{__index=Animal})
function Dog.new(name,breed)
  local self=setmetatable({},Dog)
  Animal._init(self,name,"Woof")  -- super init
  self.breed=breed
  return self
end

local d=Dog.new("Rex","Lab")
print(d.name,d.sound,d.breed)

การเริ่มต้นแบบร่วมมือกัน

ในลำดับชั้นที่ลึก แต่ละระดับจะเริ่มต้นเฉพาะฟิลด์ของตนเองและเรียก init ของคลาสแม่ วิธีนี้ทำให้แต่ละคลาสรับผิดชอบเฉพาะฟิลด์ของตนเอง

local A={}
function A._init(self,x) self.x=x end

local B={}
function B._init(self,x,y) A._init(self,x); self.y=y end

local C={}
C.__index=C
function C.new(x,y,z)
  local self=setmetatable({},C)
  B._init(self,x,y)
  self.z=z
  return self
end

local c=C.new(1,2,3)
print(c.x,c.y,c.z)  -- 1 2 3

ตัวห่อ super

สร้างตัวช่วย super(self) ที่ส่งคืนวัตถุพร็อกซีซึ่งเรียกเมธอดของคลาสแม่พร้อม self วิธีนี้ทำให้ไวยากรณ์สะอาดกว่าการเขียน Parent.method(self, ...)

local function super(self)
  local mt = getmetatable(getmetatable(self).__index)
  if mt then
    return setmetatable({}, {__index=function(_,k)
      local parentCls = mt.__index or mt
      return function(...) return parentCls[k](self,...) end
    end})
  end
end
print("super() helper pattern shown")

หลายระดับ

เมื่อมีการสืบทอดหลายระดับ แต่ละระดับจะเรียกคลาสแม่โดยตรงของตนเอง สายโซ่จะส่งต่อขึ้นไปโดยอัตโนมัติ

local L1={} L1.__index=L1
function L1:intro() return "L1" end

local L2={} L2.__index=L2
setmetatable(L2,{__index=L1})
function L2:intro() return L1.intro(self).."+L2" end

local L3={} L3.__index=L3
setmetatable(L3,{__index=L2})
function L3:intro() return L2.intro(self).."+L3" end

local obj=setmetatable({},L3)
print(obj:intro())  -- L1+L2+L3

การเพิ่มพฤติกรรมให้เมธอด

เพิ่มพฤติกรรมให้เมธอดของคลาสแม่โดยเรียกเวอร์ชันของคลาสแม่ก่อน แล้วจึงเพิ่มการทำงาน วิธีนี้คือคำแนะนำแบบ "ก่อน" หรือ "หลัง" โดยไม่ต้องใช้กรอบงาน AOP อย่างเป็นทางการ

local Logger={} Logger.__index=Logger
function Logger:log(msg) print("[LOG] "..msg) end

local TimedLogger={} TimedLogger.__index=TimedLogger
setmetatable(TimedLogger,{__index=Logger})

function TimedLogger:log(msg)
  local ts=os.date("%H:%M:%S")
  Logger.log(self,"["..ts.."] "..msg)  -- augment
end

local tl=setmetatable({},TimedLogger)
tl:log("Server started")

หลีกเลี่ยงข้อผิดพลาดในการเรียกคลาสแม่

ใช้ชื่อคลาสแม่ที่ถูกต้องเสมอในการเรียกคลาสแม่ อย่าใช้ getmetatable(self).__index เพราะการค้นหาเมตาเทเบิลอาจส่งคืนคลาสคั่นกลางแทนที่จะเป็นคลาสแม่ที่แท้จริง ควรระบุอย่างชัดเจนเพื่อความเข้าใจและความถูกต้อง

-- Correct: explicit parent reference
function Child:init(x)
  Base.init(self, x)  -- explicit, clear
end

-- Fragile: uses metatable lookup
function Child:initBad(x)
  local parent = getmetatable(getmetatable(self).__index)
  -- This may not be Base if hierarchy changes!
end
print("Be explicit with parent class references")

การเรียกคลาสแม่สำหรับ __tostring

เขียนทับ __tostring ในคลาสลูก พร้อมรวมการแสดงผลของคลาสแม่เพื่อให้ได้คำอธิบายที่ครบถ้วน

local Base={}
Base.__index=Base
Base.__tostring=function(self) return "Base("..self.name..")" end

local Child={}
Child.__index=Child
setmetatable(Child,{__index=Base})
Child.__tostring=function(self)
  local baseStr = Base.__tostring(self)
  return baseStr.." + Child(level="..self.level..")"
end

local c=setmetatable({name="X",level=5},Child)
print(tostring(c))  -- Base(X) + Child(level=5)

เมธอดแม่แบบที่ได้รับการป้องกัน

รูปแบบเมธอดแม่แบบ: คลาสพื้นฐานกำหนดโครงร่างอัลกอริทึมที่เรียกขั้นตอนนามธรรม ส่วนคลาสย่อยเป็นผู้ใช้งานขั้นตอนเหล่านั้น

local Processor={} Processor.__index=Processor
function Processor:run(data)
  data = self:preProcess(data)
  data = self:process(data)
  return self:postProcess(data)
end
function Processor:preProcess(d) return d end
function Processor:postProcess(d) return d end
function Processor:process(d) error("implement process()") end

local Upper={} Upper.__index=Upper
setmetatable(Upper,{__index=Processor})
function Upper:process(d) return d:upper() end

local p=setmetatable({},Upper)
print(p:run("hello"))  -- HELLO

ข้อตกลงการเรียกคลาสแม่

ข้อตกลงคือ ให้เติม _ หน้าฟังก์ชัน init ที่ใช้ภายในเท่านั้น (เช่น _init) และเปิดเผย new() สาธารณะเฉพาะที่ตัวสร้างระดับบนสุด วิธีนี้ทำให้สายโซ่การสืบทอดสะอาดและเป็นระเบียบ

-- Convention summary:
-- Animal._init(self, ...)  -- used for super calls
-- Dog.new(...)             -- only public constructor
-- Never call Dog._init from outside

local Foo={} Foo.__index=Foo
function Foo._init(self,x) self.x=x end
function Foo.new(x)
  return setmetatable({},Foo):_init(x) or
    (function() local s=setmetatable({},Foo); Foo._init(s,x); return s end)()
end
print("Convention: _init for super, new() for public")

คำถามเรื่องการเรียกคลาสแม่

คุณเรียกเมธอดของคลาสแม่ใน Lua อย่างไร

สรุป: การเรียกคลาสแม่

เรียกเมธอดของคลาสแม่โดยอ้างอิงคลาสอย่างชัดเจนเสมอ: Parent.method(self, ...) ใช้ข้อตกลง _init สำหรับตัวสร้างที่ทำงานร่วมกันในแต่ละระดับของการสืบทอด

คำถามที่พบบ่อย

บทเรียน “การเรียกเมธอดของคลาสแม่ด้วย super” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเรียกเมธอดของคลาสแม่ด้วย super” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเรียกเมธอดของคลาสแม่ด้วย super”

เรียกเมธอดของคลาสฐานอย่างชัดเจนเพื่อการกำหนดค่าเริ่มต้นแบบทำงานร่วมกัน คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การเรียกเมธอดของคลาสแม่ด้วย super” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

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