클로저를 통한 접근
Coddy Lua 여정의 객체 지향 프로그래밍 (Object Oriented Programming) 섹션에 포함된 레슨. 70개 중 45번째.
Private local 변수는 절대 상호 작용할 수 없다면 쓸모가 없습니다. 해결책은 closure의 스코프에 접근할 수 있는 inside the constructor에서 getter와 setter methods를 Define하는 것입니다.
이러한 methods는 :new() 내부에서 생성되므로 local 변수를 "볼" 수 있습니다. 이를 객체에 directly 할당합니다:
local Counter = {}
Counter.__index = Counter
function Counter:new()
local count = 0 -- 비공개 변수
local obj = {}
-- 생성자 내부에 메서드 정의
function obj:getCount()
return count
end
function obj:increment()
count = count + 1
end
setmetatable(obj, Counter)
return obj
end이제 private count 변수에 접근할 수 있지만, 여러분이 제공하는 methods를 통해서만 가능합니다:
local c = Counter:new()
print(c:getCount()) -- 0
c:increment()
c:increment()
print(c:getCount()) -- 2
print(c.count) -- nil (여전히 숨겨져 있음!):getCount()와 :increment()가 클래스 테이블이 아니라 obj에 직접 정의되어 있다는 점에 주목하세요. 각 인스턴스는 이러한 함수의 자체 복사본을 가지며, 각 함수는 자신만의 private count에 접근할 수 있습니다. 이것이 절충점입니다. 메서드가 프로토타입을 통해 공유되지 않으므로 진정한 privacy에는 약간 더 많은 메모리 비용이 듭니다.
챌린지
쉬움클로저 기반 privacy를 사용하여 온도 값을 섭씨로 저장하고, 제어된 접근을 제공하도록 getter와 setter methods를 constructor 내부에 정의하는 Temperature class를 만들어 봅시다!
코드를 두 개의 파일로 구성합니다:
Temperature.lua: constructor 내부의 local 변수에 온도 값이 저장되는 class를 만드세요. 외부 접근으로부터 완전히 hidden되어야 합니다. constructor:new(initialCelsius)는 온도를 local 변수에 저장한 다음, 다음 methods를 object instance에 directly 정의해야 합니다::getCelsius(): 현재 온도를 Celsius로 반환합니다:setCelsius(value): 온도를 새 값으로 업데이트합니다:getFahrenheit():(celsius * 9/5) + 32Formula를 사용하여 Fahrenheit로 converted된 온도를 반환합니다
main.lua: Temperature module을 Require하고 input에서 두 값을 read합니다. 하나는 initial 온도이고, 다른 하나는 설정할 새 온도입니다. initial 값으로 Temperature instance를 Create하고 Celsius와 Fahrenheit readings를 print한 다음, setter를 사용하여 온도를 change하고 두 readings를 다시 print합니다.
두 개의 input을 받습니다:
- Celsius 단위의 initial 온도(숫자)
- 설정할 새 온도(숫자)
출력에는 change 전후의 온도 readings를 보여 주는 네 줄이 있어야 합니다:
Celsius: {initialValue}
Fahrenheit: {convertedInitial}
Celsius: {newValue}
Fahrenheit: {convertedNew}예를 들어 input이 0과 100이면 출력은 다음과 같아야 합니다:
Celsius: 0
Fahrenheit: 32
Celsius: 100
Fahrenheit: 212온도 값은 :new() 내부의 local 변수에 저장해야 하며, self에 저장해서는 안 됩니다. getter와 setter methods는 constructor 내부에 정의되므로 closure를 통해 이 private 변수에 access할 수 있습니다. temp.celsius 또는 temp._celsius에 directly access하려고 하면 nil을 반환해야 합니다!
직접 해보기
-- Temperature 모듈 불러오기
local Temperature = require('Temperature')
-- 입력 값 읽기
local initialTemp = tonumber(io.read())
local newTemp = tonumber(io.read())
-- TODO: 초기 값으로 Temperature 인스턴스 생성
-- TODO: 초기 섭씨 및 화씨 측정값 출력
-- TODO: setter를 사용하여 온도를 newTemp로 변경
-- TODO: 업데이트된 섭씨 및 화씨 측정값 출력
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍 (Object Oriented Programming)의 모든 레슨
직접 연습해 보세요: 온라인 Lua 컴파일러