수색…
소개
루아 자체는 클래스 시스템을 제공하지 않습니다. 그러나 몇 가지 트릭 만 있으면 클래스와 객체를 테이블로 구현할 수 있습니다.
통사론
function <class>.new() return setmetatable({}, {__index=<class>}) end
간단한 객체 지향
다음은 매우 간단한 클래스 시스템을 수행하는 방법에 대한 기본 예제입니다.
Class = {}
local __instance = {__index=Class} -- Metatable for instances
function Class.new()
local instance = {}
setmetatable(instance, __instance)
return instance
-- equivalent to: return setmetatable({}, __instance)
end
변수 및 / 또는 메소드를 추가하려면 클래스에 추가하십시오. 두 인스턴스 모두 모든 인스턴스에 대해 재정의 될 수 있습니다.
Class.x = 0
Class.y = 0
Class:getPosition()
return {self.x, self.y}
end
그리고 클래스의 인스턴스를 만들려면 :
object = Class.new()
또는
setmetatable(Class, {__call = Class.new}
-- Allow the class itself to be called like a function
object = Class()
그리고 그것을 사용하려면 :
object.x = 20
-- This adds the variable x to the object without changing the x of
-- the class or any other instance. Now that the object has an x, it
-- will override the x that is inherited from the class
print(object.x)
-- This prints 20 as one would expect.
print(object.y)
-- Object has no member y, therefore the metatable redirects to the
-- class table, which has y=0; therefore this prints 0
object:getPosition() -- returns {20, 0}
객체의 메타 메서드 변경하기
갖는
local Class = {}
Class.__meta = {__index=Class}
function Class.new() return setmetatable({}, Class.__meta)
메타 테이블을 사용하여 단일 인스턴스 object = Class.new()
의 비헤이비어를 변경하려는 경우,
피해야 할 몇 가지 실수가 있습니다.
setmetatable(object, {__call = table.concat}) -- WRONG
이렇게하면 이전 메타 테이블을 새 메타 테이블로 교환하므로 클래스 상속을 위반하게됩니다.
getmetatable(object).__call = table.concat -- WRONG AGAIN
표 "값"은 참조 용 일뿐입니다. 실제로 생성자가 1 로 정의되지 않은 한 객체의 모든 인스턴스에 대해 하나의 실제 테이블 만 존재하므로이 작업을 통해 클래스의 모든 인스턴스의 동작을 수정합니다.
이 작업을 수행하는 한 가지 올바른 방법은 다음과 같습니다.
수업을 변경하지 않고 :
setmetatable(
object,
setmetatable(
{__call=table.concat},
{__index=getmetatable(object)}
)
)
이게 어떻게 작동합니까? - 실수로 # 1과 같은 새 메타 테이블을 만들지 만 비워 두지 않고 원래 메타 테이블에 대한 부드러운 복사본을 만듭니다. 새로운 메타 테 이블은 클래스 인스턴스 인 것처럼 원래의 메타 테 이블로부터 상속 받았다고 말할 수 있습니다. 이제 원본 metatable의 값을 수정하지 않고 무시할 수 있습니다.
수업 변경 :
1 위 (권장) :
local __instance_meta = {__index = Class.__meta}
-- metatable for the metatable
-- As you can see, lua can get very meta very fast
function Class.new()
return setmetatable({}, setmetatable({}, __instance_meta))
end
2 위 (덜 권장) : 1 참조
1 function Class.new() return setmetatable({}, {__index=Class}) end