수색…


소개

루아 자체는 클래스 시스템을 제공하지 않습니다. 그러나 몇 가지 트릭 만 있으면 클래스와 객체를 테이블로 구현할 수 있습니다.

통사론

  • 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



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow