Python

객체지향 프로그래밍

gudwns5533 2026. 5. 28. 20:56
프로그래밍 방법론

 

프로그래밍 방법론은 프로그램을 개발하는 다양한 접근 방식이나 철학을 뜻한다. 프로젝트 규모, 요구 사항, 개발 팀의 특성에 따라 적합한 방법론이 달라지기 때문에 각 방법론의 특징과 장단점을 이해하는 게 중요하다.

 

1. 절차적 프로그래밍 (Procedural Programming)

 

절차(Procedure)를 중시하는 방식으로, 작업을 순서대로 실행하도록 프로그램을 구성한다. 코드가 명령문으로 이루어져 있고, 작업 순서가 중요하다. 변수와 함수가 함께 사용되며, 함수를 통해 프로그램의 기능을 분리하고, 코드 중복을 줄인다.

 

2. 객체지향 프로그래밍 (OOP, Object-Oriented Programming)

 

객체(Object)라는 개념을 사용해 프로그램을 구성한다. 객체는 데이터(속성)와 함수(메서드)를 하나의 단위로 묶은 것을 말한다. 클래스라는 틀을 이용해 객체를 정의하고, 이를 통해 여러 개의 객체를 생성할 수 있다. 캡슐화(Encapsulation), 상속(Inheritance), 다형성(Polymorphism), 추상화 (Abstractioni) 등의 특징을 활용해 코드를 재사용하고 확장할 수 있다.

 

3. 함수형 프로그래밍 (Functional Programming)

 

함수를 중심으로 프로그램을 구성한다. 수학적인 함수 개념에 기초하고 있으며 코드가 간결하고 직관적이다. 예를 들어 map, filter, reduce 등의 함수나 재귀를 주로 사용하여 데이터 처리를 간결하게 수행한다.


클래스

 

클래스(class)는 객체지향 프로그래밍에서 데이터(속성)와 기능(메서드)을 하나로 묶어 객체를 만들기 위한 설계도(템플릿)이다. 클래스를 정의하면 그 구조를 기반으로 여러 개의 객체(인스턴스)를 생성할 수 있으며, 각 객체는 동일한 구조를 가지면서도 서로 다른 값을 가질 수 있다.

  • 클래스(class) : 객체를 만들기 위한 설계도 또는 틀
  • 객체(object) / 인스턴스(instance) : 설계도를 바탕으로 메모리에 실제로 구현된 실체

객체(인스턴스) 생성

 

클래스를 정의한 후에는 이를 기반으로 객체(인스턴스)를 생성할 수 있다.

class Fruit:
    pass         # 내용이 없는 블록을 만들 때 사용
    
Fruit()          # 객체로서 생성
# <__main__.Fruit at 0x2abbc5e0d70>

apple = Fruit()
print(apple)
print(type(apple))
print(id(apple))

# <__main__.Fruit object at 0x000002ABBC644B30>
# <class '__main__.Fruit'>
# 2936623352624

 

객체와 인스턴스

 

객체(object)와 인스턴스(instance)는 거의 같은 의미로 사용되지만, 관점에 따라 구분된다.

객체는 메모리에 생성된 모든 실체를 의미하는 포괄적인 개념으로, 파이썬에서 리스트, 함수, 클래스 등 모든 값이 객체.

인스턴스는 특정 클래스에 의해 생성된 객체를 가리키는 관계 중심의 용어로, "어떤 클래스의 인스턴스이다"라고 표현.

즉, 모든 인스턴스는 객체이지만, 모든 객체가 특정 클래스의 인스턴스라고 강조해서 부르는 것은 아니며, 인스턴스라는 용어는 주로 클래스와의 관계를 설명할 때 사용된다.


생성자

 

파이썬에서 생성자(Constructor)는 클래스의 인스턴스가 생성될 때 자동으로 호출되는 특별한 메서드이다.

생성자는 객체의 초기화를 담당하며, 객체가 생성될 때 필요한 속성을 초기화하고 설정하는 역할을 한다.

파이썬에서 생성자 메서드는 __init__이라고 이름이 정해져 있다.

속성을 self를 사용하여 접근하고 설정한다.

이렇게 초기화된 속성은 객체가 생성될 때 마다 다른 값을 가질 수 있다.

class 클래스이름:
    # 생성자
    def __init__(self, 매개변수1, 매개변수2):
        self.속성1 = 매개변수1
        self.속성2 = 매개변수2

 

인스턴스 변수

 

인스턴스 변수는 각 인스턴스(객체)마다 별도로 생성되는 변수로, 객체를 만들 때마다 self 키워드를 통해 생성자(init 메서드)에서 정의되며, 각 객체가 고유한 값을 따로 저장한다. 인스턴스 변수는 인스턴스명으로만 접근 가능하며, 다른 인스턴스에 영향을 주지 않고 자신만의 데이터를 가질 수 있어 객체마다 다른 속성값을 저장할 때 사용된다.

class Fruit:
    def __init__(self):
        self.name = ''
        self.quantity = 0
        
        # name, quantity = 인스턴스 변수

apple = Fruit()
print(apple.name)
print(apple.quantity)

banana = Fruit()
print(banana)
print(banana.name)
print(banana.quantity)

메서드

 

메서드(method)는 클래스 내부에 정의된 함수로, 객체(인스턴스)나 클래스와 관련된 동작(행동)을 수행하는 기능이다.

파이썬에서는 메서드의 종류에 따라 self를 사용하는 인스턴스 메서드, cls를 사용하는 클래스 메서드(@classmethod), 그리고 별도의 참조 없이 독립적으로 동작하는 정적 메서드(@staticmethod)로 나뉜다.

메서드는 단순한 함수와 달리 특정 객체나 클래스와 연결되어 동작하며, 객체의 상태(속성)를 읽거나 변경하는 역할을 한다.

class Fruit:
    def __init__(self, name, quantity):
        self.name = name
        self.quantity = quantity

    # 인스턴스 메서드
    def print_info(self):
        print(f"과일 이름: {self.name}")
        print(f"수량: {self.quantity}")

    # 인스턴스 메서드
    def add_quantity(self, amount):
        self.quantity += amount
        print(f"{amount}개 추가되었습니다.")
        
apple = Fruit("사과", 10)
apple.print_info()
apple.add_quantity(5)
apple.print_info()

# 과일 이름: 사과
# 수량: 10
# 5개 추가되었습니다.
# 과일 이름: 사과
# 수량: 15

banana = Fruit('바나나', 3)
banana.print_info()
banana.add_quantity(2)
banana.print_info()           # 메소드는 공유하지만 메소드의 self때문에 각 객체마다의 값은 다르게 관리된다.

# 과일 이름: 바나나
# 수량: 3
# 2개 추가되었습니다.
# 과일 이름: 바나나
# 수량: 5
class Order:
    tax_rate = 0.1  # 클래스 변수 (세율: 모든 주문 공통)    # 공용으로 쓰는 변수

    def __init__(self, price, quantity):
        self.price = price        # 상품 가격
        self.quantity = quantity  # 수량                  # 생성자 안의 변수 : 인스턴스 변수

    # 인스턴스 메서드
    def total_price(self):
        return self.price * self.quantity

    # 클래스 메서드 -> 객체를 따로 생성하지않고 클래스 이름으로 바로 호출할 수 있다.
    @classmethod   # 데코레이터
    def set_tax_rate(cls, rate):              # cls : 클래스의 주소가 들어있음 > 클래스 변수에 접근할 수 있음
        cls.tax_rate = rate

    # 정적 메서드 -> 클래스 이름으로 접근은 가능하지만, 클래스 변수나 self 모든 걸 사용할 수 없음. 독립적으로 사용되는 함수를 만들 때 사용
    @staticmethod
    def calculate_discount(price, discount_rate):
        return price * (1 - discount_rate)
        
# 인스턴스 생성
order1 = Order(10000, 2)  # 10000원 상품 2개

# 인스턴스 메서드 호출
print("총 가격:", order1.total_price())  # 20000

# 정적 메서드 사용 (할인 계산)
discounted = Order.calculate_discount(order1.total_price(), 0.2)
print("할인 적용 가격:", discounted)  # 16000

# 클래스 메서드 사용 (세율 변경)
Order.set_tax_rate(0.2)
print("변경된 세율:", Order.tax_rate)  # 0.2

# 총 가격: 20000
# 할인 적용 가격: 16000.0
# 변경된 세율: 0.2

 

데코레이터

 

데코레이터(decorator)는 기존 함수나 메서드를 수정하지 않고, 그 기능을 감싸서(포장해서) 추가 동작을 붙여주는 기능으로, 실행 전후에 로그를 출력하거나 권한 체크, 시간 측정 등의 공통 기능을 쉽게 재사용할 수 있게 해준다. 내부적으로는 함수를 인자로 받아 새로운 함수를 반환하는 구조로 동작하며, @데코레이터이름 형태로 사용하면 해당 함수가 자동으로 데코레이터에 전달되어 기능이 확장된다. 또한 데코레이터는 클로저의 형태로 만들어져 있다.

 

클래스 변수

 

클래스 변수는 클래스에 속하는 변수로, 클래스가 생성될 때 정의되며 그 클래스로 만들어진 모든 인스턴스(객체)들이 공유하는 변수이다. 클래스 변수는 클래스명으로 직접 접근하거나 인스턴스명으로 접근할 수 있지만, 모든 인스턴스가 같은 메모리 공간의 값을 참조하기 때문에 한 인스턴스에서 값을 변경하면 다른 인스턴스에서도 변경된 값을 볼 수 있다. 주로 전체 객체에 공통적이 속성을 저장할 때 사용한다.

class Fruit:
    origin = "한국"  # 클래스 변수 (공통 속성)

    def __init__(self, name, quantity):
        # 인스턴스 변수 (각 객체마다 다름)
        self.name = name
        self.quantity = quantity

    def print_info(self):
        print(f'원산지: {Fruit.origin}')   # 클래스 변수
        print(f'이름: {self.name}')        # 인스턴스 변수
        print(f'수량: {self.quantity}')    # 인스턴스 변수
        
apple = Fruit('사과', 10)
banana = Fruit('바나나', 5)

apple.print_info()
banana.print_info()

# 원산지: 한국
# 이름: 사과
# 수량: 10
# 원산지: 한국
# 이름: 바나나
# 수량: 5
Fruit.origin = '필리핀'   # 클래스 변수 변경

apple.print_info()
banana.print_info()

# 원산지: 필리핀           # 한국 > 필리핀으로 모두 변경된걸 알 수 있다 
# 이름: 사과
# 수량: 10
# 원산지: 필리핀
# 이름: 바나나
# 수량: 5

'Python' 카테고리의 다른 글

예외처리  (0) 2026.05.29
객체지향 프로그램 4대 패러다임  (1) 2026.05.28
사용자 정의 함수 part2  (0) 2026.05.28
사용자 정의 함수 part1  (0) 2026.05.28
이터러블(Iterable)과 이터레이터(Iterator)  (0) 2026.05.27