# Part 4: 객체 지향 프로그래밍 (OOP) 마스터하기 **⬅️ 이전 시간: [Part 3: 파이썬 컬렉션 심화](./part_3_python_collections.md)** **➡️ 다음 시간: [Part 5: AI 핵심 라이브러리](part_5_ai_core_libraries.md)** --- ## 1. 학습 목표 (Learning Objectives) 이번 파트가 끝나면, 여러분은 다음을 할 수 있게 됩니다. - 클래스(설계도)를 정의하고, 그로부터 고유한 속성과 행동을 가진 객체(제품)를 생성할 수 있습니다. - 상속을 통해 기존 클래스의 기능을 재사용하고, 메서드 오버라이딩으로 기능을 확장/변경할 수 있습니다. - 다형성을 활용하여 유연하고 확장성 높은 코드를 작성할 수 있습니다. - 캡슐화로 데이터를 안전하게 보호하고, 추상화로 클래스의 필수 기능을 강제할 수 있습니다. - 현실 세계의 문제를 객체들 간의 상호작용으로 모델링하여 체계적인 프로그램을 설계할 수 있습니다. ## 2. 핵심 키워드 (Keywords) `클래스(Class)`, `객체(Object)`, `상속(Inheritance)`, `다형성(Polymorphism)`, `캡슐화(Encapsulation)`, `추상화(Abstraction)`, `@dataclass`, `super()`, `매직 메서드(Magic Methods)` ## 3. OOP와 함께 '붕어빵 비즈니스' 시작하기 (Introduction) 지금까지 우리는 프로그래밍의 '재료'를 다듬는 법을 익혔습니다. 이번 주차에는 이 재료들을 조합하여 '요리'를 하는 법, 즉 더 크고 체계적인 프로그램을 만드는 **[객체 지향 프로그래밍(OOP)](glossaries/part_4_glossary.md#객체-지향-프로그래밍oop)** 패러다임을 학습합니다. Scikit-learn, PyTorch 등 대부분의 AI 라이브러리는 OOP에 기반하며, `model = RandomForestClassifier()` 와 같은 코드는 OOP를 이해해야 그 구조를 꿰뚫어 볼 수 있습니다. > **💡 핵심 비유: OOP는 '붕어빵 비즈니스'입니다** > OOP의 모든 개념을 '붕어빵 장사'에 빗대어 이해해 봅시다! > - **클래스(Class)**: 붕어빵을 만드는 **'붕어빵 틀'** > - **객체(Object)**: 붕어빵 틀에서 찍어낸 **'붕어빵'** 하나하나 > - **속성(Attribute)**: 붕어빵의 '팥', '슈크림' 같은 **'속재료'** > - **메서드(Method)**: 붕어빵 틀의 **'굽기()', '뒤집기()'** 같은 **'행동'** > [!TIP] > 본 파트의 모든 예제 코드는 `source_code/part_4_object_oriented_programming.py` 파일에서 직접 실행해볼 수 있습니다. --- ## 4. 클래스와 객체: 붕어빵 틀과 붕어빵 > **🎯 1일차 목표:** 클래스(Class)와 객체(Object)의 개념을 이해하고, `__init__`과 `self`를 사용하여 객체의 고유한 상태를 만듭니다. - **클래스(Class)**: 객체를 만들기 위한 **'설계도'** 또는 '붕어빵 틀'. - **객체(Object)**: 클래스로부터 생성된 **'실체'** 또는 '팥 붕어빵', '슈크림 붕어빵'. ```python from dataclasses import dataclass @dataclass # __init__, __repr__ 등 반복적인 코드를 자동 생성 class Bungeoppang: # --- 속성 (붕어빵의 속재료) --- flavor: str price: int = 1000 # 기본값 설정 # --- 메서드 (붕어빵 틀의 행동) --- def sell(self): print(f"{self.flavor} 붕어빵을 {self.price}원에 판매합니다.") # --- 객체 생성 (붕어빵 틀로 붕어빵을 찍어냄) --- red_bean_bpp = Bungeoppang("팥") shu_cream_bpp = Bungeoppang("슈크림", price=1200) # --- 메서드 호출 (붕어빵 판매) --- red_bean_bpp.sell() # "팥 붕어빵을 1000원에 판매합니다." shu_cream_bpp.sell() # "슈크림 붕어빵을 1200원에 판매합니다." ``` > **`__init__`과 `self`**: `@dataclass`가 자동으로 만들어주는 `__init__`은 붕어빵 틀에 반죽과 **앙금(`flavor`, `price`)**을 넣는 과정입니다. `self`는 지금 만들어지고 있는 **'바로 그 붕어빵'** 자신을 가리키는 대명사로, 붕어빵들이 서로의 앙금을 헷갈리지 않게 해줍니다. --- ## 5. 상속: 새로운 맛의 붕어빵 출시하기 > **🎯 2일차 목표:** 상속으로 코드 중복을 줄이고, 메서드 오버라이딩과 `super()`로 기능을 확장합니다. **상속(Inheritance)**은 '기본 붕어빵 틀'을 물려받아 '피자 붕어빵 틀' 같은 신제품을 만드는 것입니다. ```python @dataclass class PizzaBungeoppang(Bungeoppang): # Bungeoppang 클래스를 상속 topping: str # --- 메서드 오버라이딩(Method Overriding) --- # 부모의 sell() 메서드를 신제품에 맞게 재정의 def sell(self): print(f"'{self.topping}' 토핑이 올라간 {self.flavor} 피자 붕어빵을 {self.price}원에 판매합니다!") # super() 사용 예시 @dataclass class PremiumBungeoppang(Bungeoppang): origin: str def __post_init__(self): # super()는 부모 클래스를 의미. 부모의 기능을 확장할 때 사용. # 여기서는 Bungeoppang의 속성을 그대로 쓰되, 가격만 500원 인상 self.price += 500 ``` > **메서드 오버라이딩과 `super()`**: 기본 붕어빵의 판매 방식(`sell`)을 피자 붕어빵에 맞게 바꾸는 것이 **오버라이딩**입니다. 프리미엄 붕어빵을 만들 때, 기존 가격 정책에 추가 금액만 더하는 것처럼 부모의 기능을 그대로 활용하며 확장할 때 **`super()`**를 사용합니다. --- ## 6. 다형성과 캡슐화: 유연하고 안전한 비즈니스 > **🎯 3일차 목표:** 다형성(Polymorphism)으로 코드의 유연성을 높이고, 캡슐화(Encapsulation)로 데이터를 안전하게 보호합니다. - **다형성(Polymorphism)**: "주문하신 것 나왔습니다!" 라는 **동일한 요청(`sell()`)**에 대해, 대상 객체가 '팥 붕어빵'이냐 '피자 붕어빵'이냐에 따라 **다른 결과가 나오는 것**입니다. 코드의 유연성을 크게 높여줍니다. - **캡슐화(Encapsulation)**: 붕어빵 맛의 핵심인 **'반죽의 비밀 레시피(`__secret_recipe`)'**를 외부에서 함부로 바꾸지 못하게 숨기고, 정해진 방법으로만 접근하게 하여 데이터를 보호하는 것입니다. ```python class BungeoppangFactory: def __init__(self, initial_flour_kg): self.__flour_kg = initial_flour_kg # 밀가루 재고(비밀 데이터) def get_stock(self): # 데이터를 확인하는 정해진 통로 (getter) return self.__flour_kg def add_flour(self, amount): # 데이터를 변경하는 정해진 통로 (setter) if amount > 0: self.__flour_kg += amount factory = BungeoppangFactory(100) # factory.__flour_kg = 999 #! 직접 수정 불가 (AttributeError) factory.add_flour(20) # 정해진 방법으로만 수정 가능 print(f"현재 밀가루 재고: {factory.get_stock()}kg") ``` --- ## 7. 추상화와 매직 메서드: 비즈니스 규칙과 마법 > **🎯 4일차 목표:** 추상화로 클래스의 필수 기능을 강제하고, 매직 메서드로 파이썬 내장 기능을 커스터마이징합니다. - **추상화(Abstraction)**: 프랜차이즈 본사에서 "모든 가맹점은 반드시 **'굽기()' 기능을 스스로 구현해야 한다**"는 '운영 매뉴얼'을 만들어 규칙을 강제하는 것입니다. - **매직 메서드(Magic Methods)**: `print(붕어빵)`을 했을 때 예쁜 설명이 나오게 하거나(`__str__`), `붕어빵1 + 붕어빵2` 처럼 객체 간의 연산을 정의하는 등, 파이썬의 내장 기능을 우리 객체에 맞게 만드는 마법입니다. ```python from abc import ABC, abstractmethod class FranchiseManual(ABC): # 추상 클래스 @abstractmethod # 추상 메서드 def bake(self): pass class MyStore(FranchiseManual): # 가맹점 def bake(self): # '굽기' 규칙을 반드시 구현해야 함 print("우리 가게만의 방식으로 붕어빵을 굽습니다.") # --- 매직 메서드 예시 --- # Bungeoppang 클래스에 아래 메서드를 추가했다고 가정 # def __str__(self): return f"{self.flavor} 붕어빵" # def __eq__(self, other): return self.flavor == other.flavor bpp1 = Bungeoppang("팥") print(bpp1) # __str__ 호출 -> "팥 붕어빵" bpp2 = Bungeoppang("팥") print(bpp1 == bpp2) # __eq__ 호출 -> True ``` --- ## 8. 직접 해보기 (Hands-on Lab) ### 문제 1: 온라인 서점 시스템 모델링 - `Book`(책), `Member`(회원), `Order`(주문) 클래스를 `dataclass`를 사용하여 정의하고, 회원이 여러 권의 책을 주문하는 시나리오를 코드로 구현하세요. **요구사항:** - **`Book`**: `isbn`, `title`, `price` 속성 - **`Member`**: `member_id`, `name` 속성 - **`Order`**: `member`(`Member` 객체), `books`(`Book` 객체 리스트) 속성 및 `total_price()` (총 가격 계산) 메서드 ### 문제 2: 게임 캐릭터 클래스 만들기 - 기본 `Character` 클래스와 이를 상속받는 `Warrior`, `Wizard` 클래스를 만드세요. **요구사항:** - **`Character`**: `name`, `hp`, `power` 속성 및 `attack(other)` 메서드 - **`Warrior`**: `attack` 메서드를 오버라이딩하여, 20% 확률로 2배의 데미지를 입히도록 수정 - **`Wizard`**: `attack` 메서드를 오버라이딩하고, `super()`를 사용하여 부모의 공격을 먼저 실행한 뒤, 자신의 `hp`를 회복하는 기능 추가 --- ## 9. 되짚어보기 (Summary) 이번 주차에는 '붕어빵 비즈니스'를 통해 객체 지향 프로그래밍(OOP)을 배웠습니다. - **클래스와 객체**: '붕어빵 틀'과 '붕어빵'으로 설계도와 실체를 구분했습니다. - **상속**: '기본 틀'을 물려받아 '신제품 틀'을 만들며 코드 재사용성을 높였습니다. - **다형성**: "주문하신 것 나왔습니다!" 라는 동일한 요청에 여러 종류의 붕어빵이 나갈 수 있는 유연성을 배웠습니다. - **캡슐화와 추상화**: '비밀 레시피'를 보호하고(캡슐화), '프랜차이즈 매뉴얼'로 필수 기능을 강제(추상화)했습니다. OOP는 복잡한 AI 라이브러리의 구조를 이해하고, 더 크고 체계적인 프로그램을 만드는 핵심 열쇠입니다. ## 10. 더 깊이 알아보기 (Further Reading) - [파이썬 공식 튜토리얼: 클래스](https://docs.python.org/ko/3/tutorial/classes.html) - [Real Python: Object-Oriented Programming (OOP) in Python 3](https://realpython.com/python3-object-oriented-programming/)