코스 7: Six Classes - 객체지향 프로그래밍
코스 개요
이 코스에서 학생들은 객체지향 프로그래밍(OOP)의 기초를 배웁니다. 클래스를 사용하면 데이터와 기능을 하나로 묶어 재사용 가능한 '설계도'를 만들 수 있습니다. 이것은 현대 소프트웨어 개발의 핵심 패러다임으로, 대규모 프로젝트를 체계적으로 관리하는 데 필수적입니다.
예상 소요 시간: 12~24시간
소요 시간은 학생의 학년, 사전 경험, 학습 속도에 따라 크게 달라집니다. 또한 기본 개념만 익히고 넘어가는 경우와 추가 실습 문제나 창의적 프로젝트를 더 진행하는 경우에 따라서도 차이가 납니다. 위 시간은 평균적인 범위이며, 자녀의 페이스에 맞추어 유연하게 진행하시기 바랍니다.
어떤 능력을 키우게 되나요?
현실 세계를 데이터 모델로 표현하는 능력을 훈련합니다. 클래스는 "사용자에게는 이름, 이메일, 가입일이 있다"처럼 현실의 개념을 데이터 구조로 정의하는 방법입니다. 데이터베이스 설계, API 설계, AI 모델 설계 모두 이 데이터 모델링 능력이 필요합니다.
어떤 원리를 배우나요?
- (데이터 모델) 클래스로 "Player는 체력, 위치, 점수를 가진다"고 정의하면서, 현실 개념을 데이터로 모델링하는 법을 배웁니다. 이것이 데이터베이스 테이블 설계의 기초입니다.
- (데이터 계층) 상속으로 "Enemy는 캐릭터의 일종이다"라는 관계를 표현하면서, 데이터 간의 관계와 계층을 구조화하는 법을 배웁니다.
AI 시대 사고력: 컴퓨팅 (문제해결) | 데이터 기반 | 확률적 사고력
컴퓨팅 사고력 (Computational Thinking)
| 스킬 | 설명 | 활동 예시 |
|---|---|---|
| 🔷 추상화 | 공통 특성 추출하여 일반화 | "모든 적"의 공통점 → Enemy 클래스 |
| 🌳 계층화 | 상위/하위 관계로 구조화 | Block → GrassBlock, StoneBlock |
| 📋 재사용 | 한 번 정의, 여러 번 사용 | Player 클래스로 100명 생성 |
| 🛡️ 캡슐화 | 데이터와 기능을 하나로 묶기 | 체력과 데미지 받기를 함께 |
수학적 연결고리
| 수학 개념 | 프로그래밍 적용 | 학습 효과 |
|---|---|---|
| 집합과 원소 | 클래스 = 집합, 객체 = 원소 | "Enemy 집합의 원소 enemy1" |
| 분류와 범주 | 상속으로 카테고리 분류 | 동물 → 포유류 → 개 |
| 속성 | self.health = 100 |
객체의 특성값 |
| 연산/함수 | def attack(self): |
객체가 수행하는 행동 |
클래스 = 설계도 (Blueprint)
클래스 (설계도) 객체 (실제 제품)
┌───────────────┐ ┌───────────────┐
│ Player │ │ player1 │
│ ───────── │ → │ health: 100 │
│ health │ │ position: (0,0)│
│ position │ └───────────────┘
│ ───────── │ ┌───────────────┐
│ move() │ → │ player2 │
│ attack() │ │ health: 80 │
└───────────────┘ │ position: (5,3)│
└───────────────┘
상속 = 확장 (Inheritance)
Block (부모 클래스)
├── 공통 속성: position, color
└── 공통 메서드: destroy()
↓ 상속
GrassBlock (자식) StoneBlock (자식)
- hardness: 1 - hardness: 5
- 잔디 색상 - 돌 색상
+ 잔디 특수 효과 + 돌 특수 효과
실생활 분류 체계
| 상위 클래스 | 하위 클래스 | 공통점 | 차이점 |
|---|---|---|---|
| 동물 | 개, 고양이 | 움직임, 소리냄 | 짖기 vs 야옹 |
| 도형 | 원, 사각형 | 넓이 계산 | 공식 다름 |
| 탈것 | 자동차, 비행기 | 이동 | 땅 vs 하늘 |
💻 코드 예시 & 시각화
예시 1: 플레이어 클래스
class Player:
"""플레이어 클래스 - 설계도"""
def __init__(self, name):
"""생성자: 객체 초기화"""
self.name = name
self.health = 100
self.score = 0
def take_damage(self, amount):
"""데미지 받기"""
self.health -= amount
def collect_coin(self):
"""코인 획득"""
self.score += 10
# 객체 생성 (인스턴스화)
player1 = Player("철수")
player2 = Player("영희")
클래스와 객체 관계:
classDiagram
class Player {
+name: str
+health: int
+score: int
+take_damage(amount)
+collect_coin()
}
Player <|-- player1 : 인스턴스
Player <|-- player2 : 인스턴스
예시 2: 상속 구조 - 블록 시스템
class Block:
"""모든 블록의 부모 클래스"""
def __init__(self, x, y):
self.x = x
self.y = y
self.hardness = 1
class GrassBlock(Block):
"""잔디 블록"""
def __init__(self, x, y):
super().__init__(x, y)
self.hardness = 1
class StoneBlock(Block):
"""돌 블록"""
def __init__(self, x, y):
super().__init__(x, y)
self.hardness = 5
상속 다이어그램:
classDiagram
Block <|-- GrassBlock
Block <|-- StoneBlock
Block <|-- WaterBlock
class Block {
+x: int
+y: int
+hardness: int
+destroy()
}
class GrassBlock {
+hardness: 1
+color: green
}
class StoneBlock {
+hardness: 5
+color: gray
}
객체지향이란?
개념 설명
객체지향 프로그래밍은 현실 세계를 모델링하는 방식입니다:
| 현실 세계 | 프로그래밍 |
|---|---|
| 자동차 설계도 | 클래스 (Class) |
| 실제 자동차 | 객체 (Object/Instance) |
| 색상, 속도 | 속성 (Attributes) |
| 가속, 정지 | 메서드 (Methods) |
"자동차" 클래스로 "빨간 스포츠카", "파란 트럭" 등 여러 객체를 만들 수 있습니다.
프로젝트 1: Digging Player - 클래스 메서드와 속성
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 플레이어 클래스 설계하기 |
| 핵심 개념 | 클래스 정의, 속성, 메서드 |
class Player:로 플레이어의 설계도를 만듭니다. self.health = 100은 각 플레이어가 가지는 속성(데이터)입니다. def move(self, direction):은 플레이어가 수행할 수 있는 메서드(행동)입니다. 학생들은 데이터와 기능을 하나로 묶는 것의 장점을 배웁니다. 플레이어가 100명이어도 같은 클래스로 일관된 방식으로 관리할 수 있습니다.
init 메서드 (생성자)
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 객체 초기화하기 |
| 핵심 개념 | 생성자, 초기화, self |
def __init__(self):는 객체가 생성될 때 자동으로 호출됩니다. 여기서 객체의 초기 상태를 설정합니다 - 체력 100, 위치 (0, 0) 등. self는 "이 객체 자신"을 의미하며, self.health는 "이 객체의 체력"입니다. 학생들은 각 객체가 독립적인 상태를 가진다는 것을 이해합니다. 플레이어 A의 체력이 줄어도 플레이어 B의 체력은 영향받지 않습니다.
self의 의미
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 객체 참조 이해하기 |
| 핵심 개념 | 인스턴스 참조, 메서드 호출 |
self는 메서드가 "어떤 객체에서 호출되었는지" 알게 해줍니다. player1.move()를 호출하면 self는 player1을, player2.move()에서는 player2를 가리킵니다. 학생들은 같은 메서드가 다른 객체에서 다르게 동작할 수 있다는 것을 배웁니다. 이것은 객체지향의 핵심 개념 중 하나입니다. 처음에는 혼란스러울 수 있지만 연습을 통해 자연스러워집니다.
프로젝트 2: FPS Enemy - 클래스와 객체 생성
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 적 AI 클래스 만들기 |
| 핵심 개념 | 여러 인스턴스, AI 패턴 |
class Enemy:로 적의 공통 행동을 정의합니다. enemy1 = Enemy(), enemy2 = Enemy()로 여러 적을 생성합니다. 각 적은 자신만의 위치, 체력, 상태를 독립적으로 유지합니다. 학생들은 하나의 클래스로 수십, 수백 개의 객체를 효율적으로 관리하는 방법을 배웁니다. 적이 플레이어를 추적하거나 패턴대로 이동하는 간단한 AI도 구현합니다.
프로젝트 3: Minecraft Block - 상속과 다형성
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 클래스 확장하기 |
| 핵심 개념 | 상속, 다형성, 코드 재사용 |
상속은 기존 클래스를 확장하여 새 클래스를 만드는 것입니다. class GrassBlock(Block):은 Block의 모든 기능을 물려받고 추가 기능을 더합니다. 학생들은 코드 중복 없이 다양한 종류의 블록을 만들 수 있습니다. 다형성은 같은 메서드 이름이 클래스마다 다르게 동작하는 것입니다. 예: block.break()가 돌 블록은 천천히, 흙 블록은 빨리 부서지게 할 수 있습니다.
왜 상속을 사용하나요?
| 항목 | 내용 |
|---|---|
| 무엇을 배우나요? | 코드 재사용의 원리 |
| 핵심 개념 | DRY 원칙, 계층 구조 |
Block 클래스에 공통 기능(위치, 파괴, 상호작용)을 두고, GrassBlock, StoneBlock, WaterBlock 등이 상속받아 확장합니다. 공통 코드는 한 번만 작성하고 여러 곳에서 재사용합니다. 버그 수정이나 기능 추가도 한 곳에서만 하면 모든 하위 클래스에 적용됩니다. 이것은 DRY(Don't Repeat Yourself) 원칙의 실현입니다. 대규모 프로젝트에서 유지보수 가능한 코드를 만드는 핵심 기술입니다.
객체지향의 장점
왜 배워야 하나요?
- 조직화: 관련된 데이터와 기능이 함께 묶임
- 재사용: 한 번 만든 클래스를 여러 프로젝트에서 사용
- 확장성: 기존 코드를 수정하지 않고 새 기능 추가
- 협업: 팀원들이 각자 다른 클래스를 개발 가능
- 현실 모델링: 실제 세계의 개념을 자연스럽게 표현
현대의 거의 모든 대규모 소프트웨어(게임, 웹사이트, 앱)는 객체지향으로 설계됩니다.
이 코스를 마치면...
학습 성과
학생들은 다음 능력을 갖추게 됩니다:
- 클래스를 정의하고 객체를 생성할 수 있음
__init__으로 객체를 초기화할 수 있음self를 사용하여 객체의 속성과 메서드에 접근할 수 있음- 상속으로 기존 클래스를 확장할 수 있음
- 다형성의 개념을 이해하고 활용할 수 있음
- 게임의 플레이어, 적, 아이템을 체계적으로 설계할 수 있음