재정의와 다형성
부모 메서드를 재정의하고 실행 시 다형성 디스패치를 구현합니다.
재정의와 다형성은(는) CoddyKit의 무료 Lua Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Lua Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
메서드 재정의
자식 클래스는 같은 이름의 메서드를 정의해 부모 메서드를 재정의합니다. 자식 인스턴스에서 호출하면 자식 버전이 실행됩니다. Parent.method(self)를 통해 부모 버전에도 계속 접근할 수 있습니다.
local Shape={} Shape.__index=Shape
function Shape:area() return 0 end
function Shape:describe() print(type(self).." area="..self:area()) end
local Circle={} Circle.__index=Circle
setmetatable(Circle,{__index=Shape})
function Circle.new(r) return setmetatable({r=r},Circle) end
function Circle:area() return math.pi*self.r^2 end
local Square={} Square.__index=Square
setmetatable(Square,{__index=Shape})
function Square.new(s) return setmetatable({s=s},Square) end
function Square:area() return self.s^2 end
Circle.new(5):describe()
Square.new(4):describe()다형적 디스패치
다형성이란 서로 다른 객체 유형이 같은 메시지에 서로 다르게 응답하는 것입니다. 어떤 "도형"이든 받을 수 있고 :area()를 호출하는 함수는 모든 도형 유형에서 작동하며, 각 도형은 자체 구현으로 응답합니다.
local shapes={
Circle.new(3),
Square.new(4),
Circle.new(1),
}
local total=0
for _,shape in ipairs(shapes) do
total=total+shape:area()
end
print(string.format("Total area: %.2f",total))덕 타이핑
Lua는 덕 타이핑을 사용합니다. 객체에 해당 메서드가 있으면 작동합니다. 정식 인터페이스 선언은 필요하지 않습니다. :speak()을 호출하는 함수는 클래스와 관계없이 speak 메서드를 가진 모든 객체에서 작동합니다.
local function makeNoise(obj)
if type(obj.speak)=="function" then
obj:speak()
else
print("(silent)")
end
end
local Duck={speak=function(self) print("Quack!") end}
local Robot={speak=function(self) print("Beep boop!") end}
local Rock={}
makeNoise(Duck) -- Quack!
makeNoise(Robot) -- Beep boop!
makeNoise(Rock) -- (silent)연산자 다형성
__add와 같은 메타메서드는 연산자에 다형성을 적용할 수 있게 합니다. 서로 다른 유형이 __add를 정의하기만 하면 +에 각자의 의미로 응답할 수 있습니다.
local Vec2={} Vec2.__index=Vec2
Vec2.__add=function(a,b) return Vec2.new(a.x+b.x,a.y+b.y) end
Vec2.__tostring=function(v) return "("..v.x..","..v.y..")" end
function Vec2.new(x,y) return setmetatable({x=x,y=y},Vec2) end
local Color={} Color.__index=Color
Color.__add=function(a,b)
return Color.new(math.min(255,a.r+b.r),math.min(255,a.g+b.g),math.min(255,a.b+b.b))
end
function Color.new(r,g,b) return setmetatable({r=r,g=g,b=b},Color) end
print(tostring(Vec2.new(1,2)+Vec2.new(3,4))) -- (4,6)방문자 패턴
방문자 패턴은 연산과 객체를 분리합니다. 연산은 서로 다른 유형의 객체를 "방문"하고, 유형에 따라 적절한 메서드를 호출합니다. 유형을 수정하지 않고 유형별로 달라져야 하는 연산에 사용하십시오.
local function printInfo(obj)
local mt = getmetatable(obj)
if mt == Circle then
print(string.format("Circle r=%.1f area=%.2f",obj.r,obj:area()))
elseif mt == Square then
print(string.format("Square s=%.1f area=%.2f",obj.s,obj:area()))
end
end
for _,s in ipairs({Circle.new(3),Square.new(4)}) do
printInfo(s)
end인터페이스 테이블
메서드 이름의 테이블로 인터페이스를 정의하십시오. 객체를 다형적으로 사용하기 전에 필요한 모든 메서드를 구현했는지 확인하십시오.
local function implements(obj, interface)
for _, method in ipairs(interface) do
if type(obj[method]) ~= "function" then
return false, "missing: "..method
end
end
return true
end
local Drawable = {"draw","resize","move"}
local Widget = {
draw=function(self) print("draw "..self.type) end,
resize=function(self,w,h) self.w,self.h=w,h end,
move=function(self,x,y) self.x,self.y=x,y end,
type="button"
}
local ok,err = implements(Widget,Drawable)
print(ok,err) -- true nil메서드 존재 여부 확인
선택적 메서드를 다형적으로 호출하기 전에 객체가 해당 메서드를 가지고 있는지 확인하십시오. 이렇게 하면 공통 기본 클래스를 요구하지 않고 선택적 기능을 사용할 수 있습니다.
local function maybeUpdate(obj, dt)
if type(obj.update)=="function" then
obj:update(dt)
end
end
local objects={
{x=0,y=0,update=function(self,dt) self.x=self.x+10*dt end},
{x=0,y=0}, -- no update
{x=0,y=0,update=function(self,dt) self.y=self.y+5*dt end},
}
for _,o in ipairs(objects) do maybeUpdate(o,1) end
for _,o in ipairs(objects) do print(o.x,o.y) end유형 기반 디스패치 테이블
if/elseif 연쇄문 대신 디스패치 테이블을 사용하십시오. 유형 이름을 처리 함수에 매핑하는 방식입니다. 이는 테이블 기반 다형성 패턴입니다.
local handlers={
number = function(v) return "num:"..v end,
string = function(v) return "str:\"".."..v.."\"" end,
boolean = function(v) return "bool:"..(v and "T" or "F") end,
table = function(v) return "tbl:#"..tostring(#v) end,
}
local function describe(v)
local h=handlers[type(v)]
return h and h(v) or "unknown"
end
print(describe(42))
print(describe("hello"))
print(describe({1,2,3}))공변 반환
자식 메서드는 부모 메서드보다 더 구체적인 유형을 반환할 수 있습니다(공변 반환). Lua는 동적 유형 지정 언어이므로 이것이 자연스럽습니다. 자식의 팩토리는 부모 인스턴스가 아니라 자식 인스턴스를 반환합니다.
local Base={} Base.__index=Base
function Base.new() return setmetatable({type="base"},Base) end
function Base:copy() return Base.new() end
local Child={} Child.__index=Child
setmetatable(Child,{__index=Base})
function Child.new(extra)
local self=setmetatable({type="child"},Child)
self.extra=extra; return self
end
function Child:copy() return Child.new(self.extra) end -- covariant
local c=Child.new("hello")
local c2=c:copy()
print(c2.extra,getmetatable(c2)==Child) -- hello true다형성 요약
실제 Lua 다형성은 같은 메서드 이름이 유형마다 다른 동작을 수행하는 방식입니다. 메타테이블 기반 객체 지향 프로그래밍, 덕 타이핑 확인 또는 디스패치 테이블을 통해 구현할 수 있습니다. 정식 인터페이스 시스템은 필요하지 않으며, 일관된 메서드 이름 규칙만 있으면 됩니다.
-- Three ways to achieve polymorphism:
-- 1. Metatable inheritance + method override
-- 2. Duck typing: just call it if it exists
-- 3. Dispatch table: map type -> handler
local function area(shape)
-- Duck typing approach:
assert(type(shape.area)=="function","needs area()")
return shape:area()
end
print(area({area=function() return 16 end})) -- 16다형성 질문
Lua에서 다형성은 어떻게 작동하나요?
복습: 재정의와 다형성
자식 클래스에서 부모 메서드를 다시 정의해 재정의하십시오. Lua는 __index 연결을 따라 아래에서 위로 호출을 확인하므로 실행 중 다형적 디스패치를 자연스럽게 구현할 수 있습니다.
자주 묻는 질문
“재정의와 다형성” 강의는 무료인가요?
네 — “재정의와 다형성” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Lua Academy 강의 전체를 잠금 해제할 수 있습니다. Lua Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“재정의와 다형성”에서 뭘 배우나요?
부모 메서드를 재정의하고 실행 시 다형성 디스패치를 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Lua Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Lua Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Lua Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“재정의와 다형성” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Lua Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Lua Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.