Account = { balance = 0 }
function Account.withdraw(value)
Account.balance = Account.balance - value
end
Account.withdraw(100.0)
위와 같이 테이블에 값을 저장하는 변수와 함수를 정의해서 객체처럼 정의할 수 있다.
그런데 withdraw 함수를 보면 "Account." 으로 인해 Account 직접 명시해서 접근하고 있다. 객체지향적 관점(특히 상속)으로 보면 이것은 매우 안좋다.
다른 언어에서 사용하듯이 lua도 "self" 식별자를 이용해서 자신을 가리키는 메커니즘을 제공한다.
function Account.withdraw(value)
self.balance = self.balance - value
end
그렇다면 위 정의가 instance를 생성하려면 어떻게 해야 하는가?
다른 언어에서도 구조가 비슷하듯이 Lua에서 클래스와 인스턴스, 상속등의 구조를 만드려면 metatable을 이용해야 한다.
앞에 Chapter에서 말했듯이, table은 table마다 metatable을 다르게 가져갈 수 있다. 하지만 객체 지향 구조를 만들기 위해서는 instance가 되는 table들이 같은 Class table을 metatable로 가지도록 만들어야 한다.
Account = { balance = 0 }
function Account:withdraw(value)
self.balance = self.balance - value
end
function Account:new()
local instance = { balance = 0 }
setmetatable(instance, self)
self.__index = self
return instance
end
accountA = Account:new()
accountB = Account:new()
accountA:withdraw(30)
accountB:withdraw(20)
print(accountA.balance)
print(accountB.balance)
accountA:withdraw(20)
print(accountA.balance)
위 코드에서 accountA, accountB는 클래스 Account의 instance이고, metatable로 클래스 Account를 가지고 있다.
accountA:withdraw(30)를 호출하면 accountA 테이블에는 withdraw 함수가 존재하지 않으니 metatable의 __index를 참조해서 withdraw 함수를 찾아서 호출한다.
즉 getmetatable(accountA).__index.withdraw(30) 이 실행된다.
'Lua Script' 카테고리의 다른 글
[Lua] 메타테이블과 메타메서드 (0) | 2018.03.28 |
---|---|
[Lua] 반복자 (0) | 2018.03.28 |
[Lua] 함수의 내부 (0) | 2018.03.28 |
[Lua] 함수 (0) | 2018.03.27 |
[Lua] 문장 (0) | 2018.03.27 |