Has-A 관계
Coddy Lua 여정의 객체 지향 프로그래밍 (Object Oriented Programming) 섹션에 포함된 레슨. 70개 중 49번째.
이 과정 전체에서 클래스 간 동작을 공유하기 위해 상속을 사용했습니다. Dog는 Animal의 "일종"입니다. 하지만 상속이 항상 올바른 도구인 것은 아닙니다.
때때로 객체들은 가족 트리를 공유하지 않습니다. 대신 한 객체가 단순히 다른 객체를 포함합니다. 이를 composition이라고 하며, "has-a" 관계를 모델링합니다.
자동차를 생각해 보세요. 자동차는 엔진의 유형이 아닙니다. 자동차에는 엔진이 있습니다. 엔진은 자동차 내부에 존재하는 별도의 객체입니다.
local Engine = {}
Engine.__index = Engine
function Engine:new(horsepower)
local obj = {horsepower = horsepower}
setmetatable(obj, Engine)
return obj
end
local Car = {}
Car.__index = Car
function Car:new(model, engine)
local obj = {
model = model,
engine = engine -- Car 안에 Engine 객체를 저장
}
setmetatable(obj, Car)
return obj
end자동차를 생성할 때 기존 engine 객체를 해당 생성자에 전달합니다:
local myEngine = Engine:new(200)
local myCar = Car:new("Sedan", myEngine)
print(myCar.engine.horsepower) -- 200자동차는 engine에서 상속받지 않습니다. 단순히 engine에 대한 참조를 보유할 뿐입니다. 이렇게 하면 두 클래스가 서로 독립적으로 유지됩니다. 다른 engine으로 교체하거나, 오토바이에서 동일한 engine 클래스를 사용할 수도 있습니다.
Composition은 상속으로는 얻을 수 없는 유연성을 제공합니다. 객체를 경직된 계층 구조에 가두는 대신 여러 부분으로 조립할 수 있기 때문입니다.
챌린지
쉬움구성을 사용하여 컴퓨터 시스템을 만들어 봅시다! 상속 대신, 내부에 CPU를 가지고 있는 Computer를 만들 것입니다. 이를 통해 "has-a" 관계를 보여 줍니다.
코드를 세 개의 파일로 구성합니다:
CPU.lua: 브랜드 이름과 속도를 GHz 단위로 저장하는:new(brand, speed)생성자를 포함한 CPU 클래스를 만듭니다.{brand} @ {speed}GHz형식의 문자열을 반환하는:getInfo()메서드를 포함합니다.Computer.lua::new(model, cpu)생성자가 모델 이름과 CPU 객체를 받는 Computer 클래스를 만듭니다. Computer는 CPU 객체를 내부에 저장합니다(구성!). 컴퓨터의 모델과 CPU의 정보를 출력하는:describe()메서드를 포함합니다.main.lua: 모든 것을 하나로 연결합니다! CPU 브랜드, CPU 속도, 컴퓨터 모델을 입력받습니다. 먼저 CPU 객체를 만든 다음, 이를 Computer 생성자에 전달합니다. 마지막으로 컴퓨터의:describe()메서드를 호출합니다.
세 개의 입력을 받습니다:
- CPU 브랜드(문자열)
- GHz 단위의 CPU 속도(숫자)
- 컴퓨터 모델 이름(문자열)
출력에는 포함된 CPU의 정보가 들어 있는 컴퓨터 설명이 표시되어야 합니다:
Model: {model}
CPU: {brand} @ {speed}GHz예를 들어 입력이 Intel, 3.5, WorkStation이라면 출력은 다음과 같아야 합니다:
Model: WorkStation
CPU: Intel @ 3.5GHzComputer가 CPU를 상속하지 않는다는 점에 주목하세요. Computer는 단순히 CPU에 대한 참조를 보유합니다. Computer의 :describe() 메서드는 저장된 객체를 통해 CPU의 데이터에 접근하며, 이를 통해 구성을 사용하면 더 단순한 부분들로 복잡한 객체를 만들 수 있음을 보여 줍니다!
직접 해보기
-- main.lua
-- 컴포지션을 사용하여 모든 것을 결합합니다
local CPU = require('CPU')
local Computer = require('Computer')
-- 입력 읽기
local cpuBrand = io.read()
local cpuSpeed = tonumber(io.read())
local computerModel = io.read()
-- TODO: 브랜드와 속도로 CPU 객체를 생성합니다
-- TODO: 모델과 CPU 객체로 Computer 객체를 생성합니다
-- TODO: computer의 describe() 메서드를 호출하여 출력을 인쇄합니다
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍 (Object Oriented Programming)의 모든 레슨
직접 연습해 보세요: 온라인 Lua 컴파일러