공통 요소와 고유 요소
Coddy Lua 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 70개 중 35번째.
상속을 다룰 때는 각 데이터 조각이 어디에 위치하는지 이해하는 것이 중요합니다. 일부 속성은 공유됩니다. 즉, 부모 클래스에서 정의되어 모든 자식 클래스에서 접근할 수 있습니다. 다른 속성들은 고유합니다. 즉, 자식 클래스나 인스턴스에서 구체적으로 생성됩니다.
다음 계층 구조를 고려해 보세요:
local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia" -- 공유됨: 클래스에 정의됨
function Animal:new(name)
local obj = {name = name} -- 고유함: 각 인스턴스에 저장됨
setmetatable(obj, Animal)
return obj
endlocal Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark" -- 모든 Dog 간에 공유됨
function Dog:new(name, breed)
local obj = Animal.new(Animal, name)
obj.breed = breed -- 고유함: 각 Dog는 자신만의 품종(breed)을 가짐
setmetatable(obj, Dog)
return obj
endDog 인스턴스를 생성할 때, 일부 값은 객체에 직접 존재하며 다른 값들은 룩업 체인(lookup chain)을 통해 찾을 수 있습니다:
local rex = Dog:new("Rex", "German Shepherd")
-- 이 인스턴스에 고유함 (rex에 저장됨)
print(rex.name) -- "Rex"
print(rex.breed) -- "German Shepherd"-- 공유됨 (조회를 통해 찾음)
print(rex.sound) -- "bark" (Dog에서 가져옴)
print(rex.kingdom) -- "Animalia" (Animal에서 가져옴)핵심적인 차이점: 생성자에서 obj에 할당된 필드는 각 인스턴스에 고유한 반면, 클래스 테이블에 직접 정의된 필드는 해당 클래스와 그 자식 클래스의 모든 인스턴스 간에 공유됩니다.
챌린지
쉬움Creature와 Dragon 클래스 시스템을 구축하여 상속 계층 구조를 통해 데이터가 어떻게 흐르는지 살펴보겠습니다. 모든 인스턴스에서 공유되는 속성과 각 개별 객체에 고유한 속성이 무엇인지 직접 확인하게 될 것입니다.
코드는 다음 세 개의 파일로 구성됩니다:
Creature.lua: 모든 생명체가 공유하는 클래스 수준의 공유 속성world = "Fantasy Realm"을 가진 부모 클래스를 정의합니다. 생명체의 이름을 인스턴스 속성으로 저장하는:new(name)생성자를 포함하세요.Dragon.lua: Creature를 상속받는 자식 클래스를 정의합니다. 모든 드래곤이 공유하는 클래스 수준의 공유 속성element = "fire"를 추가하세요.:new(name, color)생성자는 이름 설정을 위해 부모 생성자를 호출한 다음, 각 드래곤의 고유한 인스턴스 속성으로color를 추가해야 합니다.main.lua: 두 마리의 서로 다른 드래곤을 생성하고 속성을 검사하여 공유 데이터와 고유 데이터의 차이점을 보여줍니다.
두 개의 입력을 받게 됩니다:
- 첫 번째 드래곤의 이름과 색상, 쉼표로 구분됨 (예:
Smaug,red) - 두 번째 드래곤의 이름과 색상, 쉼표로 구분됨 (예:
Draco,gold)
메인 파일에서 각각의 이름과 색상을 가진 두 드래곤을 생성하세요. 그런 다음 아래 정보를 정확히 이 순서대로 출력하세요:
- 첫 번째 드래곤의
name - 첫 번째 드래곤의
color - 두 번째 드래곤의
name - 두 번째 드래곤의
color - 첫 번째 드래곤의
element(Dragon 클래스에서 공유됨) - 두 번째 드래곤의
element(Dragon 클래스에서 공유됨) - 첫 번째 드래곤의
world(Creature 클래스에서 공유됨)
예를 들어, 입력이 Smaug,red와 Draco,gold라면 출력은 다음과 같아야 합니다:
Smaug
red
Draco
gold
fire
fire
Fantasy Realmname과 color는 각 드래곤마다 다르지만(고유 인스턴스 속성), element와 world는 두 드래곤 모두에게 동일함(조회 체인을 통해 발견되는 공유 클래스 속성)을 확인해 보세요.
치트 시트
상속 계층 구조에서 속성은 공유되거나(클래스 테이블에 정의됨) 고유할(개별 인스턴스에 저장됨) 수 있습니다.
공유 속성은 클래스 테이블에 직접 정의되며 메타테이블 조회 체인을 통해 액세스됩니다:
local Animal = {}
Animal.__index = Animal
Animal.kingdom = "Animalia" -- 모든 Animal에 걸쳐 공유됨고유 속성은 생성자에서 인스턴스 객체(obj)에 할당됩니다:
function Animal:new(name)
local obj = {name = name} -- 각 인스턴스마다 고유함
setmetatable(obj, Animal)
return obj
end자식 클래스는 부모 속성을 상속받으면서 자신만의 공유 속성을 가질 수 있습니다:
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
Dog.sound = "bark" -- 모든 Dog 사이에서 공유됨
function Dog:new(name, breed)
local obj = Animal.new(Animal, name) -- 부모 생성자 호출
obj.breed = breed -- 고유한 자식 속성 추가
setmetatable(obj, Dog)
return obj
end속성 액세스:
local rex = Dog:new("Rex", "German Shepherd")
-- 고유 (rex에 직접 저장됨)
print(rex.name) -- "Rex"
print(rex.breed) -- "German Shepherd"
-- 공유 (메타테이블 조회를 통해 찾음)
print(rex.sound) -- "bark" (Dog 클래스에서 가져옴)
print(rex.kingdom) -- "Animalia" (Animal 클래스에서 가져옴)직접 해보기
-- main.lua: 드래곤을 생성하고 공유 속성 대 고유 속성을 시연합니다.
local Dragon = require('Dragon')
-- 첫 번째 드래곤의 입력값(이름, 색상)을 읽습니다.
local input1 = io.read()
-- 두 번째 드래곤의 입력값(이름, 색상)을 읽습니다.
local input2 = io.read()
-- TODO: 첫 번째 입력을 파싱하여 이름과 색상을 추출하세요.
-- 힌트: "([^,]+),([^,]+)" 패턴과 함께 string.match를 사용하세요.
-- TODO: 두 번째 입력을 파싱하여 이름과 색상을 추출하세요.
-- TODO: 이름과 색상을 사용하여 첫 번째 드래곤을 생성하세요.
-- TODO: 이름과 색상을 사용하여 두 번째 드래곤을 생성하세요.
-- TODO: 다음을 순서대로 출력하세요:
-- 1. 첫 번째 드래곤의 이름
-- 2. 첫 번째 드래곤의 색상
-- 3. 두 번째 드래곤의 이름
-- 4. 두 번째 드래곤의 색상
-- 5. 첫 번째 드래곤의 속성 (Dragon 클래스에서 공유됨)
-- 6. 두 번째 드래곤의 속성 (Dragon 클래스에서 공유됨)
-- 7. 첫 번째 드래곤의 세계 (Creature 클래스에서 공유됨)
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.