여러 믹스인 적용하기
Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 52번째.
하나의 믹스인은 클래스에 하나의 동작 집합을 추가합니다. 하지만 실제 객체는 종종 여러 소스로부터의 기능이 필요합니다. 게임 객체는 이리저리 움직여야 할 수도 있고 동시에 화면에 보여야 할 수도 있습니다. 이는 동일한 믹스인에 속하지 않는 두 개의 별개 관심사입니다.
해결 방법은 간단합니다. 동일한 클래스에 여러 믹스인(mixin)을 적용하면 됩니다. 각 믹스인은 고유한 메서드를 제공하며, 클래스는 이 모든 메서드를 갖게 됩니다:
local Movable = {}
function Movable:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
local Visible = {}
function Visible:show()
print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
print("Hidden")
end이전과 동일한 헬퍼 함수를 사용하여 두 믹스인 모두를 클래스에 적용하세요:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local GameObject = {}
GameObject.__index = GameObject
applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)이제 GameObject 인스턴스들은 이동과 자기 자신을 표시하는 것 모두를 할 수 있습니다:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- 5, 3 위치에 표시 중한 가지 주의할 점: 두 개의 믹스인이 동일한 메서드 이름을 정의하는 경우, 두 번째로 적용된 것이 첫 번째 것을 덮어쓰게 됩니다. 예기치 않은 동작을 방지하려면 믹스인 메서드를 고유하게 유지하세요.
챌린지
쉬움믹스인(mixins)을 사용하여 여러 기능을 결합한 게임용 Character 클래스를 만들어 봅시다! 여러분의 캐릭터는 적을 공격하고 스스로를 치유할 수 있는 두 가지 뚜렷한 행동을 가지게 되며, 이 행동들은 각각 별도의 믹스인에서 가져옵니다.
코드는 다음 네 개의 파일로 구성됩니다:
Attacker.lua:{self.name} attacks {targetName} for {self.damage} damage!를 출력하는:attack(targetName)메서드를 가진 믹스인을 만듭니다. (객체에name과damage필드가 있다고 가정합니다.)Healer.lua:self.health에 양(amount)을 더하고{self.name} heals for {amount}. Health: {newHealth}를 출력하는:heal(amount)메서드를 가진 믹스인을 만듭니다.Character.lua: 세 가지 속성을 저장하는 생성자:new(name, health, damage)를 가진 Character 클래스를 만듭니다. 모든 캐릭터가 공격과 치유를 할 수 있도록 Attacker와 Healer 믹스인을 모두 적용하세요.{name} - Health: {health}, Damage: {damage}를 출력하는:status()메서드를 포함하세요.main.lua: 여기에applyMixin헬퍼 함수를 작성하세요. 캐릭터의 이름, 체력, 공격력, 공격할 대상, 치유량에 대한 입력을 읽습니다. Character를 생성하고, 상태를 표시하고, 대상을 공격하게 하고, 스스로를 치유하게 한 다음, 다시 상태를 표시합니다.
다섯 개의 입력을 받게 됩니다:
- 캐릭터 이름 (문자열)
- 시작 체력 (숫자)
- 공격력 값 (숫자)
- 공격할 대상 이름 (문자열)
- 치유할 양 (숫자)
출력은 캐릭터가 두 믹스인 능력을 모두 사용하는 모습을 보여주어야 합니다:
{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}예를 들어, 입력값이 Warrior, 100, 25, Goblin, 30인 경우 출력은 다음과 같아야 합니다:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25각 믹스인은 Character 클래스에 고유한 메서드를 제공합니다. 캐릭터는 어느 믹스인으로부터도 상속받지 않으며, 단순히 applyMixin 함수를 통해 그 능력을 얻습니다. 이것이 여러 믹스인을 결합하는 힘입니다!
치트 시트
여러 개의 믹스인(mixin)을 단일 클래스에 적용하여 서로 다른 동작 세트를 결합할 수 있습니다. 각 믹스인은 클래스에 고유한 메서드를 제공합니다.
서로 다른 관심사에 대해 별도의 믹스인을 정의합니다:
local Movable = {}
function Movable:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
local Visible = {}
function Visible:show()
print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
print("Hidden")
endapplyMixin 헬퍼 함수를 사용하여 클래스에 여러 믹스인을 적용합니다:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local GameObject = {}
GameObject.__index = GameObject
applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)이제 클래스는 적용된 모든 믹스인의 메서드를 갖게 됩니다:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- Showing at 5, 3중요: 만약 두 개의 믹스인이 동일한 메서드 이름을 정의하는 경우, 두 번째로 적용된 믹스인이 첫 번째 것을 덮어씁니다. 충돌을 피하기 위해 믹스인 간에 메서드 이름을 고유하게 유지하십시오.
직접 해보기
-- 메인 파일
-- TODO: applyMixin 헬퍼 함수 작성
-- 이 함수는 믹스인 테이블의 모든 메서드를 대상 테이블로 복사해야 합니다.
local function applyMixin(target, mixin)
-- TODO: 믹스인 적용 구현
end
-- Character.lua에서 사용할 수 있도록 applyMixin을 전역으로 설정
_G.applyMixin = applyMixin
local Character = require('Character')
-- 입력 읽기
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())
-- TODO: 주어진 이름, 체력, 공격력으로 Character 생성
-- TODO: 캐릭터의 상태 표시
-- TODO: 캐릭터가 대상을 공격하게 함
-- TODO: 캐릭터가 자신을 치유하게 함
-- TODO: 캐릭터의 상태를 다시 표시
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.