Menu
Coddy logo textTech

클로저를 통한 접근

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에는 약간 더 많은 메모리 비용이 듭니다.

challenge icon

챌린지

쉬움

클로저 기반 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) + 32 Formula를 사용하여 Fahrenheit로 converted된 온도를 반환합니다
  • main.lua: Temperature module을 Require하고 input에서 두 값을 read합니다. 하나는 initial 온도이고, 다른 하나는 설정할 새 온도입니다. initial 값으로 Temperature instance를 Create하고 Celsius와 Fahrenheit readings를 print한 다음, setter를 사용하여 온도를 change하고 두 readings를 다시 print합니다.

두 개의 input을 받습니다:

  1. Celsius 단위의 initial 온도(숫자)
  2. 설정할 새 온도(숫자)

출력에는 change 전후의 온도 readings를 보여 주는 네 줄이 있어야 합니다:

Celsius: {initialValue}
Fahrenheit: {convertedInitial}
Celsius: {newValue}
Fahrenheit: {convertedNew}

예를 들어 input이 0100이면 출력은 다음과 같아야 합니다:

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: 업데이트된 섭씨 및 화씨 측정값 출력
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍 (Object Oriented Programming)의 모든 레슨

직접 연습해 보세요: 온라인 Lua 컴파일러