💻 프로그래밍

객체지향 프로그래밍

Object-Oriented Programming

데이터와 메서드를 객체로 묶어 프로그램을 구성하는 패러다임. 캡슐화, 상속, 다형성이 핵심 개념.

📖 상세 설명

객체지향 프로그래밍(OOP)은 프로그램을 객체들의 상호작용으로 설계하는 패러다임입니다. 절차적 프로그래밍이 순차적 명령어 실행에 초점을 맞춘다면, OOP는 데이터와 그 데이터를 처리하는 메서드를 하나의 단위(객체)로 묶어 모듈화합니다.

OOP의 4대 원칙은 캡슐화, 추상화, 상속, 다형성입니다. 캡슐화는 내부 구현을 숨기고 인터페이스만 노출합니다. 추상화는 복잡한 시스템을 단순한 모델로 표현합니다. 상속은 기존 클래스를 확장하여 코드를 재사용합니다. 다형성은 같은 인터페이스로 다른 구현을 호출할 수 있게 합니다.

Java, C++, Python, C# 등 대부분의 현대 언어가 OOP를 지원합니다. 클래스는 객체의 설계도이고, 객체는 클래스의 인스턴스입니다. 클래스는 속성(필드)과 행동(메서드)을 정의하며, 객체는 실제 메모리에 할당되어 동작합니다.

OOP는 대규모 소프트웨어 개발에서 유지보수성과 확장성을 높입니다. 다만 과도한 추상화는 복잡성을 증가시킬 수 있어, SOLID 원칙과 디자인 패턴을 함께 적용하여 균형을 맞추는 것이 중요합니다.

💻 코드 예제

Python
# 객체지향 프로그래밍의 4대 원칙 예제

# 추상 클래스 (추상화)
from abc import ABC, abstractmethod

class Animal(ABC):
    def __init__(self, name):
        self._name = name  # 캡슐화: protected 속성

    @property
    def name(self):  # getter로 접근 제어
        return self._name

    @abstractmethod
    def speak(self):  # 추상 메서드
        pass

# 상속과 다형성
class Dog(Animal):
    def speak(self):
        return f"{self.name}: 멍멍!"

class Cat(Animal):
    def speak(self):
        return f"{self.name}: 야옹~"

# 다형성 활용: 동일한 인터페이스, 다른 동작
def animal_sound(animal: Animal):
    print(animal.speak())

# 사용 예시
dog = Dog("바둑이")
cat = Cat("나비")

animal_sound(dog)  # "바둑이: 멍멍!"
animal_sound(cat)  # "나비: 야옹~"

# 캡슐화: 내부 상태 보호
class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # private

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def get_balance(self):
        return self.__balance

🗣️ 실무 대화 예시

팀장
"결제 시스템에 새로운 결제 수단을 추가해야 하는데, 기존 코드 수정 없이 가능할까요?"
개발자
"PaymentProcessor 인터페이스를 구현한 새 클래스만 추가하면 됩니다. 전략 패턴으로 설계해두어서 기존 코드는 건드릴 필요 없어요."
팀장
"OCP(개방-폐쇄 원칙)가 잘 적용되어 있군요. 테스트도 새 클래스만 추가하면 되겠네요."
면접관
"상속보다 컴포지션을 선호해야 하는 이유를 설명해주세요."
지원자
"상속은 강한 결합을 만들어 부모 클래스 변경이 자식에게 영향을 줍니다. 컴포지션은 필요한 기능을 가진 객체를 포함하므로 유연하고 런타임에 동작을 변경할 수 있습니다."
면접관
"SOLID 원칙 중 리스코프 치환 원칙(LSP)이란 무엇인가요?"
지원자
"자식 클래스는 부모 클래스를 대체해도 프로그램이 정상 동작해야 합니다. 예를 들어 정사각형이 직사각형을 상속하면 너비/높이 독립 변경 시 LSP를 위반할 수 있습니다."
리뷰어
"이 클래스가 데이터 검증, 저장, 알림 전송까지 다 하고 있네요. SRP(단일 책임 원칙)에 따라 분리하는 게 좋겠어요."
작성자
"맞아요. Validator, Repository, NotificationService로 나누고 이 클래스는 조율만 하도록 수정하겠습니다."
리뷰어
"그리고 구체 클래스 대신 인터페이스에 의존하면 테스트할 때 Mock 주입도 쉬워져요."

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기