Menu
Coddy logo textTech

객체 더하기

Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 26번째.

이미 __tostring__eq와 같은 메타메소드를 통해 객체의 동작을 사용자 정의하는 방법을 살펴보았습니다. 이제 덧셈을 시작으로 이를 산술 연산까지 확장해 보겠습니다.

__add 메타메소드는 두 객체 사이에서 + 연산자를 사용할 때 어떤 일이 일어나는지를 정의합니다. Lua가 a + b를 발견하면, 두 피연산자 중 하나의 메타테이블에서 __add를 찾습니다.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

__add는 콜론이 아닌 마침표(점)로 정의된다는 점에 유의하세요. 이 함수는 두 피연산자를 인자로 받으며, 원본 중 어느 것도 수정하지 않고 새로운 객체를 반환해야 합니다. 이렇게 하면 연산을 예측 가능하고 안전하게 유지할 수 있습니다.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- 출력: 4  6

핵심적인 통찰은 __add가 객체 내부뿐만 아니라 메타테이블 자체(여기서는 Vector)에 있어야 한다는 것입니다. 모든 인스턴스에 대해 Vector를 메타테이블로 설정했으므로, 이들은 모두 이 동작을 자동으로 공유합니다.

challenge icon

챌린지

쉬움

+ 연산자를 사용하여 덧셈을 지원하는 Vector 클래스를 만들어 봅시다. 이것은 연산자 오버로딩(operator overloading)의 첫 번째 단계로, 여러분이 만든 객체가 Lua의 내장 연산자와 자연스럽게 작동하도록 만드는 과정입니다.

코드는 두 개의 파일로 구성됩니다:

  • Vector.lua: xy 컴포넌트를 가진 Vector 클래스를 정의합니다. :new(x, y) 생성자를 포함하고, 두 벡터를 더했을 때 컴포넌트가 합쳐진 새로운 벡터가 생성되도록 __add 메타메소드를 구현하세요. __add는 콜론(colon)이 아닌 점(dot) 구문을 사용하며 두 피연산자를 인자로 받는다는 점을 기억하세요.
  • main.lua: Vector 모듈을 불러오고(require), 벡터 인스턴스를 생성한 뒤, 이들을 더했을 때 올바른 결과가 나오는지 확인합니다.

네 개의 입력을 받게 됩니다:

  1. 첫 번째 벡터의 x 컴포넌트
  2. 첫 번째 벡터의 y 컴포넌트
  3. 두 번째 벡터의 x 컴포넌트
  4. 두 번째 벡터의 y 컴포넌트

메인 파일에서 주어진 컴포넌트로 두 개의 벡터를 생성하고, + 연산자를 사용하여 더한 뒤, 결과 벡터의 xy 값을 각각 별도의 줄에 출력하세요.

예를 들어, 입력값이 3, 4, 1, 2라면 출력은 다음과 같아야 합니다:

4
6

첫 번째 벡터 (3, 4)와 두 번째 벡터 (1, 2)를 더하면 새로운 벡터 (4, 6)이 됩니다.

치트 시트

__add 메타메소드는 두 객체 사이에 + 연산자를 사용할 때 어떤 일이 일어날지 정의합니다.

Lua가 a + b를 발견하면, 두 피연산자 중 하나의 메타테이블에서 __add를 찾습니다.

local Vector = {}
Vector.__index = Vector

function Vector:new(x, y)
    local obj = {x = x, y = y}
    setmetatable(obj, Vector)
    return obj
end

function Vector.__add(v1, v2)
    return Vector:new(v1.x + v2.x, v1.y + v2.y)
end

__add는 콜론이 아닌 마침표(dot)로 정의됩니다. 이 메소드는 두 피연산자를 인자로 받으며, 원본을 수정하는 대신 새로운 객체를 반환해야 합니다.

local a = Vector:new(3, 4)
local b = Vector:new(1, 2)
local c = a + b

print(c.x, c.y)  -- 출력: 4  6

__add는 객체 내부가 아니라 메타테이블 자체에 있어야 합니다.

직접 해보기

-- Vector 모듈 가져오기
local Vector = require('Vector')

-- 입력 읽기
local x1 = tonumber(io.read())
local y1 = tonumber(io.read())
local x2 = tonumber(io.read())
local y2 = tonumber(io.read())

-- TODO: 입력값을 사용하여 두 개의 Vector 인스턴스 생성

-- TODO: + 연산자를 사용하여 두 벡터 더하기

-- TODO: 결과 벡터의 x와 y 값을 별도의 줄에 출력
quiz icon실력 점검

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

Object Oriented Programming의 모든 레슨