학습
Lua OOP 개념과 구현
Lua OOP 개념과 구현 — 중급
OOP 개념과 구현
1. 도입 (왜 배워야 하는가)
객체 지향 프로그래밍(OOP)은 소프트웨어 개발에서 매우 중요한 패러다임입니다. 이는 복잡한 시스템을 더 쉽게 관리하고, 유지보수하며, 확장할 수 있도록 도와줍니다. OOP의 주요 개념인 클래스와 객체를 통해 우리는 현실 세계의 개념을 코드로 모델링할 수 있습니다. 예를 들어, 자동차라는 객체를 클래스로 정의하면, 속성(색상, 모델)과 행동(운전, 정지)을 쉽게 구현할 수 있습니다.
OOP를 모르면 다음과 같은 문제가 발생할 수 있습니다:
- 코드의 재사용성이 떨어져 중복 코드가 발생할 수 있습니다.
- 프로그램의 구조가 복잡해져 유지보수가 어려워질 수 있습니다.
- 팀원 간의 협업에서 서로 다른 코드 스타일로 인해 혼란이 생길 수 있습니다.
2. 핵심 개념 설명
OOP의 핵심 개념은 다음과 같습니다:
| 개념 | 설명 | 비유 |
|---|---|---|
| 클래스 | 객체의 설계도, 속성과 메서드를 정의합니다. | 자동차의 설계도 |
| 객체 | 클래스의 인스턴스, 실제로 사용할 수 있는 것. | 실제로 존재하는 자동차 |
| 상속 | 기존 클래스를 기반으로 새로운 클래스를 만드는 것. | 부모님의 유전자나 성격을 물려받는 것 |
| 다형성 | 같은 이름의 메서드가 서로 다른 기능을 수행하는 것. | 여러 종류의 자동차가 같은 방식으로 운전되는 것 |
| 캡슐화 | 객체의 속성과 메서드를 한 곳에 묶고, 외부에서 접근을 제한하는 것. | 자동차의 엔진이 외부에서 보이지 않는 것 |
3. 기본 코드 예제
-- 클래스 정의
Car = {}
Car.__index = Car
-- 생성자
function Car:new(color, model)
local instance = setmetatable({}, Car)
instance.color = color
instance.model = model
return instance
end
-- 메서드 정의
function Car:drive()
print(self.color .. " " .. self.model .. " is driving.")
end
-- 객체 생성
myCar = Car:new("Red", "Toyota")
myCar:drive()
실행 결과:
Red Toyota is driving.
코드 한 줄씩 동작 설명:
Car = {}: Car라는 빈 테이블을 생성하여 클래스 역할을 하게 함.Car.__index = Car: 메타테이블을 통해 Car 클래스의 인스턴스가 자신을 참조하도록 설정.function Car:new(color, model): 새로운 객체를 생성하기 위한 생성자 함수 정의.local instance = setmetatable({}, Car): 빈 테이블을 생성하고 Car 클래스를 메타테이블로 설정.instance.color = color: 객체의 색상 속성을 설정.instance.model = model: 객체의 모델 속성을 설정.return instance: 새로 생성된 객체를 반환.function Car:drive(): 자동차가 운전하는 메서드를 정의.print(self.color .. " " .. self.model .. " is driving."): 자동차의 색상과 모델을 출력.myCar = Car:new("Red", "Toyota"): Car 클래스를 사용하여 새로운 객체 myCar 생성.myCar:drive(): myCar 객체의 drive 메서드 호출.- OOP는 코드의 재사용성과 유지보수성을 높여줌.
- 클래스와 객체를 통해 현실 세계의 개념을 코드로 모델링 가능.
- 상속과 다형성을 활용하여 코드의 유연성과 확장성을 증대.
- 캡슐화를 통해 데이터 보호와 코드의 가독성을 향상.
- Lua에서의 메타테이블 활용
- Lua의 함수형 프로그래밍 개념
- 디자인 패턴 (예: 싱글턴, 팩토리 패턴)
4. 실전 활용 예제
예제 1: 쇼핑몰에서 장바구니 구현
ShoppingCart = {}
ShoppingCart.__index = ShoppingCart
function ShoppingCart:new()
local instance = setmetatable({}, ShoppingCart)
instance.items = {}
return instance
end
function ShoppingCart:addItem(item)
table.insert(self.items, item)
end
function ShoppingCart:checkout()
print("Checking out items:")
for _, item in ipairs(self.items) do
print(item)
end
end
-- 장바구니 객체 생성
myCart = ShoppingCart:new()
myCart:addItem("Apple")
myCart:addItem("Banana")
myCart:checkout()
상황 설명: 쇼핑몰에서 고객이 장바구니에 상품을 추가하고 결제할 수 있는 기능을 구현한 예제입니다.
예제 2: 동물 클래스와 상속
Animal = {}
Animal.__index = Animal
function Animal:new(name)
local instance = setmetatable({}, Animal)
instance.name = name
return instance
end
function Animal:sound()
return "Some sound"
end
Dog = setmetatable({}, {__index = Animal})
function Dog:sound()
return "Bark"
end
-- 동물 객체 생성
dog = Dog:new("Buddy")
print(dog.name .. " says " .. dog:sound())
상황 설명: 동물 클래스를 만들고, 개 클래스를 상속하여 개의 소리를 출력하는 예제입니다.
5. 흔한 실수와 주의사항
실수 1: 메서드 호출 시 self 누락
잘못된 코드:
function Car:drive()
print(self.color .. " is driving.")
end
myCar.drive() -- self가 누락됨
올바른 코드:
myCar:drive() -- self를 자동으로 전달
실수 2: 클래스의 속성에 직접 접근
잘못된 코드:
myCar.color = "Blue" -- 속성 변경
올바른 코드:
function Car:setColor(color)
self.color = color
end
myCar:setColor("Blue") -- 메서드를 통해 변경