Menu
Coddy logo textTech

부모 메서드 호출하기

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

때로는 메서드를 완전히 오버라이딩하는 것이 원하는 방식이 아닐 수도 있습니다. 대신 부모의 동작을 확장(extend)하여, 부모의 기능을 수행한 뒤에 추가적인 기능을 더하고 싶을 수 있습니다. 이를 구현하려면 자식 클래스의 오버라이딩된 메서드 내부에서 부모 메서드를 직접 호출하면 됩니다.

이 기법은 부모 클래스 이름과 함께 점(dot) 구문을 사용하며, self를 첫 번째 인수로 명시적으로 전달합니다:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

-- Dog은 부모의 동작을 확장합니다
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- 부모 메서드를 먼저 호출합니다
    print(self.name .. " wags tail happily")
end

핵심이 되는 줄은 Animal.speak(self)입니다. 부모 클래스에 점 구문을 사용하고 self를 수동으로 전달함으로써, 고유한 동작을 추가하기 전에 원래의 메서드를 호출합니다:

local buddy = Dog:new("Buddy")
buddy:speak()
-- 출력:
-- Buddy가 소리를 냅니다
-- Buddy가 꼬리를 즐겁게 흔듭니다

이 패턴은 부모 메서드가 중복하고 싶지 않은 중요한 작업을 수행할 때 유용합니다. 자식은 부모의 로직을 처음, 마지막 또는 자신의 코드 중간에 실행할 수 있어, 동작이 결합되는 방식을 완벽하게 제어할 수 있습니다.

challenge icon

챌린지

쉬움

FormalPerson이 일반 Person의 동작을 확장하는 인사 시스템을 만들어 봅시다! 정중한 버전의 사람은 자신을 소개할 때 기존 방식을 완전히 바꾸는 대신, 먼저 표준 인사를 한 다음 정중한 표현을 추가합니다.

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

  • Person.lua: 사람의 이름을 저장하는 :new(name) 생성자가 있는 기본 클래스입니다. 사람의 이름 뒤에 says hi를 출력하는 :introduce() 메서드를 포함하세요. 이것이 확장될 기본 동작입니다.
  • FormalPerson.lua: Person을 상속받는 자식 클래스입니다. 생성자는 부모 생성자를 호출하여 이름을 처리해야 합니다. :introduce() 메서드를 오버라이드하되, 부모의 동작을 완전히 대체하는 대신 Person.introduce(self)를 사용하여 부모의 메서드를 먼저 호출한 다음, 사람의 이름 뒤에 bows politely를 추가로 출력하세요.
  • main.lua: FormalPerson 모듈을 불러오고(require), 입력에서 이름을 읽어 FormalPerson 인스턴스를 생성한 후, :introduce()를 호출하여 두 동작이 결합된 결과를 확인하세요.

입력으로 사람의 이름 하나를 받게 됩니다.

FormalPerson에서 :introduce()를 호출하면 두 줄의 출력이 생성되어야 합니다. 첫 번째 줄은 부모 메서드에서, 두 번째 줄은 자식 클래스에서 추가한 내용입니다:

{name} says hi
{name} bows politely

예를 들어, 입력이 Eleanor라면 출력은 다음과 같아야 합니다:

Eleanor says hi
Eleanor bows politely

여기서 핵심은 FormalPerson이 "says hi" 로직을 중복해서 작성하지 않는다는 점입니다. 부모 메서드에 해당 작업을 위임한 다음, 그 위에 자신만의 고유한 동작을 추가합니다. 이를 통해 코드를 깔끔하게 유지하고 자식 클래스가 부모의 기능을 대체하는 대신 어떻게 확장할 수 있는지 보여줍니다!

치트 시트

부모 메서드의 동작을 완전히 재정의(override)하는 대신 확장하려면, 점(dot) 구문을 사용하고 self를 명시적으로 전달하여 자식의 재정의된 메서드 내에서 부모 메서드를 호출하세요:

function ChildClass:method()
    ParentClass.method(self)  -- 부모 메서드 호출
    -- 추가 동작 추가
end

메서드 확장을 보여주는 전체 예제:

local Animal = {}
Animal.__index = Animal

function Animal:new(name)
    local obj = {name = name}
    setmetatable(obj, Animal)
    return obj
end

function Animal:speak()
    print(self.name .. " makes a sound")
end

local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})

function Dog:new(name)
    local obj = Animal.new(Animal, name)
    setmetatable(obj, Dog)
    return obj
end

function Dog:speak()
    Animal.speak(self)  -- 먼저 부모의 동작을 실행
    print(self.name .. " wags tail happily")  -- 자식의 동작을 추가
end

local buddy = Dog:new("Buddy")
buddy:speak()
-- 출력:
-- Buddy makes a sound
-- Buddy wags tail happily

부모 메서드는 자식 고유 로직의 이전, 이후 또는 중간 등 어느 시점에서나 호출할 수 있으므로, 동작이 결합되는 방식을 완벽하게 제어할 수 있습니다.

직접 해보기

-- main.lua: 인사 시스템의 진입점

local FormalPerson = require('FormalPerson')

-- 입력으로부터 사람의 이름을 읽어옵니다
local name = io.read()

-- TODO: 주어진 이름으로 FormalPerson 인스턴스를 생성합니다

-- TODO: FormalPerson 인스턴스에서 introduce 메서드를 호출합니다
quiz icon실력 점검

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

Object Oriented Programming의 모든 레슨