Python

파이썬 클래스(Class)로 배우는 객체지향 프로그래밍

코딩 코디네이터 2025. 4. 11. 16:00
반응형

파이썬 클래스(Class)로 배우는 객체지향 프로그래밍

객체지향 프로그래밍 어렵다고 느끼셨나요?
파이썬 클래스 한 번 이해하면 생각보다 엄청 쉬워요!

 

 

안녕하세요, 여러분 😊

오늘은 파이썬의 꽃이라고도 할 수 있는 클래스(Class)객체지향 프로그래밍(OOP)에 대해 이야기해볼까 해요.

처음 접하면 '뭐가 이렇게 복잡해?' 싶지만, 실제로는 우리가 일상에서 자주 쓰는 '설계도와 실물 제품'의 관계랑 비슷해서 이해하기 쉽답니다.

이 글에서는 클래스의 기본 구조부터 메서드와 생성자, 그리고 상속오버라이딩까지, 꼭 알아야 할 핵심 개념들을 차근차근 예제와 함께 알려드릴게요.

끝까지 함께 해주시면, 여러분도 객체지향 프로그래밍이 어렵지 않다는 걸 느끼실 수 있을 거예요! 🚀

1. 클래스와 객체란? 🧱

클래스(Class)객체(Object)는 파이썬에서 객체지향 프로그래밍의 핵심 개념이에요.

이 두 가지를 이해하면 코드의 재사용성과 확장성을 높일 수 있어요.

쉽게 말해, 클래스는 설계도이고 객체는 그 설계도로 만들어진 제품이에요.

클래스와 객체의 관계

  • 클래스(Class): 반복해서 만들 수 있는 설계도
  • 객체(Object): 클래스를 통해 만들어진 실체

예를 들어,

'자동차'라는 클래스를 만들면, 이 클래스를 바탕으로 만든 여러 대의 자동차들이 객체가 되는 거죠.

각 객체는 서로 다른 속성(색상, 속도 등)을 가질 수 있고, 독립적으로 존재할 수 있어요.

기초 예제: Cookie 클래스


class Cookie:
    pass

a = Cookie()
b = Cookie()

위 예제는 아주 기본적인 클래스 정의예요.

pass는 아직 클래스 안에 아무 기능도 넣지 않았다는 뜻이에요.

그럼에도 불구하고 a, b라는 객체를 만들 수 있어요! 🤖

이처럼 클래스는 객체를 만들어낼 수 있는 ‘틀’인 셈이죠.

객체의 특징 🧩

  • 클래스에서 만든 객체는 고유한 성격을 가질 수 있음
  • 동일한 클래스라도 객체들끼리는 서로 영향 없음 (독립적!)

비유로 이해해 볼까요? ☕

카페에서 같은 메뉴의 커피를 여러 잔 주문한다고 상상해보세요.

메뉴판이 클래스라면, 주문해서 나온 커피 한 잔 한 잔이 객체예요.

커피는 메뉴는 같지만, 누군가는 시럽을 추가할 수도 있고, 누군가는 휘핑을 빼달라고 할 수도 있죠.

이렇게 객체는 각자 다르게 행동할 수 있어요.

정리 ✍️

항목 설명
클래스 객체를 만들기 위한 설계도
객체 클래스를 통해 만들어진 실체
예시 a = Cookie() → a는 Cookie 클래스의 객체

이제 클래스와 객체의 개념이 좀 감이 오시죠? 😊

다음으로는 객체 내부의 동작을 담당하는 메서드와 self에 대해 자세히 알아볼 거예요!

 

 

2. 메서드와 self 이해하기 🔁

클래스 내부에 정의된 함수는 메서드(method)라고 부릅니다.

메서드는 객체의 동작을 정의하는 도구예요.

이 메서드를 제대로 활용하려면 self라는 키워드의 개념을 먼저 이해해야 해요.

처음 보면 낯설고 헷갈릴 수 있지만, 알고 보면 생각보다 단순하답니다!

self의 정체는?

self는 객체 자기 자신을 가리키는 변수예요. 메서드 안에서 self를 통해 해당 객체의 속성이나 다른 메서드에 접근할 수 있어요.

예를 들어

어떤 객체 aa.setdata(3, 4)를 호출하면, self에는 자동으로 a가 전달됩니다.


class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second

이렇게 self.first = first는 “이 객체의 first라는 속성에 외부에서 받은 값을 넣어줘” 라는 뜻이에요. self가 없으면 객체 각각의 속성을 구분할 수 없겠죠?

self 없이 메서드를 호출하면? 🤔

만약 self를 메서드에 넣지 않으면, 파이썬은 객체가 호출한 메서드임을 인식하지 못하고 에러를 내요.

객체 메서드에는 항상 첫 번째 인자로 self가 있어야 해요.

메서드 사용 예제


a = FourCal()
a.setdata(3, 4)

print(a.first)  # 3
print(a.second) # 4

위처럼 setdata 메서드를 통해 a 객체는 firstsecond라는 두 개의 속성을 가지게 됩니다.

이 속성들은 각각의 객체에 독립적으로 존재해요.

즉, 다른 객체에는 영향을 주지 않아요!

비교 실험: 객체 간 속성 독립성


b = FourCal()
b.setdata(5, 6)

print(a.first)  # 여전히 3
print(b.first)  # 5
객체명 first 값
a 3
b 5

이렇게 같은 클래스에서 만들어졌더라도 각 객체는 서로 완전히 독립적이에요.

self를 통해 객체 각각의 데이터가 보존되고, 서로 영향을 주지 않기 때문에 가능한 일이죠.

이게 바로 객체지향의 “캡슐화(Encapsulation)” 개념이기도 해요!

다음 장에서는 객체가 만들어질 때 자동으로 호출되는 생성자 메서드 __init__()에 대해 배워볼게요.

이제 객체 생성과 초기화의 마법을 직접 경험해봅시다! ✨

 

 

3. 생성자(__init__)의 역할 🔨

파이썬에서는 객체가 생성될 때 자동으로 실행되는 특별한 메서드가 있어요.

그게 바로 __init__(), 일명 생성자(constructor)입니다.

객체를 만들자마자 초기값을 설정할 수 있게 해주는 이 메서드는 클래스 안에서 굉장히 중요한 역할을 해요.

생성자가 필요한 이유

앞에서 만든 FourCal 클래스는 setdata() 메서드로 데이터를 입력받았죠.

그런데 실수로 setdata()를 안 하고 add()를 호출하면 어떻게 될까요?


a = FourCal()
print(a.first)  # AttributeError 발생

바로 AttributeError가 발생합니다.

first 속성이 아직 존재하지 않기 때문이에요.

이런 문제를 방지하려면 객체 생성과 동시에 데이터를 넣는 방법이 필요하고, 그 해답이 바로 __init__()이에요!

생성자 사용 예제


class FourCal:
    def __init__(self, first, second):
        self.first = first
        self.second = second

    def add(self):
        return self.first + self.second

이제 객체를 만들 때 바로 값을 넣을 수 있어요 👇


a = FourCal(3, 5)
print(a.add())  # 8

멋지죠?

이렇게 하면 실수로 setdata()를 호출하지 않아 생기는 오류를 방지할 수 있고, 객체의 초기 상태도 깔끔하게 설정할 수 있어요.

생성자의 매개변수 개수 주의!

생성자를 정의할 때 __init__(self, first, second)처럼 매개변수를 정하면, 객체 생성 시에도 반드시 해당 값을 전달해야 해요.

아래처럼 파라미터 없이 생성하면 에러 발생!


a = FourCal()  # TypeError 발생

생성자와 메서드의 관계

  • 생성자는 객체를 만들 때 한 번 자동 실행됨
  • 일반 메서드는 객체가 만든 이후에 원하는 만큼 호출 가능

정리 🧾

구분 설명
__init__() 객체 생성 시 자동 호출되는 메서드
일반 메서드 필요할 때 직접 호출해야 작동

이제 여러분은 클래스가 객체를 만들 때 어떤 방식으로 초기화를 하는지, 왜 생성자가 중요한지를 이해하셨어요.

 

다음 파트에서는 객체 변수의 독립성에 대해 더 깊이 들여다볼게요. 👀

 

 

4. 객체 변수의 독립성 이해하기 🔍

객체를 여러 개 만들면, 각 객체는 서로 다른 객체 변수(instance variable)를 가질 수 있어요.

이 말은 곧 클래스는 같아도, 객체마다 저장된 값은 서로 독립적이라는 뜻이죠! 😎

이 개념은 객체지향 프로그래밍에서 아주 중요한 원칙이에요.

객체 변수란?

객체가 생성될 때 생성자나 메서드를 통해 self.변수명 형식으로 선언되는 변수예요.

이 변수는 해당 객체에만 속하며, 다른 객체에는 영향을 주지 않아요.


class FourCal:
    def setdata(self, first, second):
        self.first = first
        self.second = second

여러 객체를 생성해보자!


a = FourCal()
b = FourCal()

a.setdata(4, 2)
b.setdata(3, 7)

print(a.first)  # 4
print(b.first)  # 3

이처럼 ab는 같은 클래스에서 만들어졌지만, 각자의 first 값은 다릅니다.

하나를 수정한다고 다른 하나에 영향을 주지 않죠.

실험: 객체 변수 독립성 테스트

객체명 first 값 second 값
a 4 2
b 3 7

이걸 왜 중요하게 생각해야 할까?

  • 각각의 객체는 독립적인 데이터를 관리할 수 있어야 한다.
  • 하나의 객체의 값 변경이 전체 클래스에 영향을 주면 유지보수가 어려워짐.

이 원리를 이해하면 앞으로 클래스와 객체를 활용할 때 의도치 않은 버그를 방지할 수 있어요. 😊

 

다음 단계에서는 객체지향의 꽃이라 할 수 있는 상속(Inheritance)에 대해 배워볼 거예요.

기존 기능을 재사용하고 확장하는 아주 중요한 기능이죠!

 

 

5. 클래스 상속으로 기능 확장하기 🧬

파이썬 클래스의 가장 강력한 기능 중 하나가 바로 상속(Inheritance)이에요.

상속은 말 그대로 기존 클래스를 물려받아 새로운 클래스를 만드는 방법이에요.

기존 클래스의 기능을 그대로 사용할 수 있고, 필요한 기능만 추가하거나 바꾸면 되기 때문에 아주 효율적이죠.

기본 상속 구조 이해하기


class FourCal:
    def __init__(self, first, second):
        self.first = first
        self.second = second

    def add(self):
        return self.first + self.second

class MoreFourCal(FourCal):
    def pow(self):
        return self.first ** self.second

위 코드에서 MoreFourCal 클래스는 FourCal 클래스를 상속받아요.

그래서 FourCaladd() 메서드는 물론, __init__() 생성자까지 그대로 사용할 수 있어요.

거기에 pow()라는 새로운 기능도 추가했죠!

사용 예제


a = MoreFourCal(4, 2)

print(a.add())  # 6
print(a.pow())  # 16

이처럼 상속을 활용하면 기존 코드 재사용 + 기능 확장을 동시에 이룰 수 있어요.

코드를 반복해서 작성할 필요도 없고, 유지보수도 쉬워집니다!

상속의 구조 요약

구성 요소 의미
부모 클래스 기존 기능을 가진 클래스 (예: FourCal)
자식 클래스 부모 클래스를 상속받는 클래스 (예: MoreFourCal)
추가 기능 자식 클래스에만 정의된 새로운 메서드

상속이 실무에서 중요한 이유 🤔

  • 여러 기능을 공통으로 사용해야 하는 클래스 구조에서 코드 중복 제거
  • 새로운 기능 추가가 쉬움 (자식 클래스에서만 추가/변경하면 됨)

자, 여기까지 배우셨다면 객체지향의 핵심 중 하나인 상속에 대해 감 잡으셨을 거예요! 마지막으로, 상속받은 기능 중 일부를 오버라이딩해서 동작을 바꾸는 방법도 함께 배워볼까요?

 

 

6. 메서드 오버라이딩으로 동작 변경하기 🔁

상속을 활용하면 부모 클래스의 기능을 물려받을 수 있죠.

그런데 때로는 부모의 메서드를 그대로 쓰고 싶지 않을 때도 있어요.

예를 들어,

기존 메서드가 너무 위험하거나, 다른 방식으로 동작하길 바랄 때 말이죠.

이럴 땐 메서드 오버라이딩(method overriding)을 사용하면 됩니다!

오버라이딩이란?

부모 클래스에 정의된 메서드를 자식 클래스에서 같은 이름으로 다시 정의하는 것을 오버라이딩이라고 해요.

오버라이딩된 메서드는 부모 클래스의 메서드를 덮어쓰게 되며, 객체는 자식 클래스에 정의된 메서드를 우선 사용합니다.

예제: 나눗셈 안전하게 처리하기


class FourCal:
    def __init__(self, first, second):
        self.first = first
        self.second = second

    def div(self):
        return self.first / self.second

class SafeFourCal(FourCal):
    def div(self):
        if self.second == 0:
            return "0으로 나눌 수 없습니다!"
        return self.first / self.second

이제 SafeFourCal 클래스를 사용하면 0으로 나눌 때 오류가 발생하지 않아요.

div() 메서드를 자식 클래스에서 오버라이딩했기 때문이죠.

아래처럼 사용하면 됩니다:


a = SafeFourCal(4, 0)
print(a.div())  # 출력: 0으로 나눌 수 없습니다!

오버라이딩 요약 포인트

  • 메서드 이름과 매개변수가 같아야 함
  • 부모 클래스의 기능을 ‘내 입맛’에 맞게 바꾸는 데 유용

정리 및 마무리 💡

기능 설명
상속 부모 클래스의 기능을 자식 클래스가 그대로 물려받음
오버라이딩 부모 클래스의 메서드를 자식 클래스에서 재정의

이제 여러분은 파이썬 클래스의 기본 구조부터 객체, 메서드, 생성자, 상속 그리고 오버라이딩까지 모두 익히셨습니다! 👏

 

마지막으로 오늘 배운 내용을 정리하며 실전에서 어떻게 활용할 수 있을지 살펴보고, 블로그 포스트를 마무리해볼게요.

 

 

마무리 🧭

오늘은 파이썬의 객체지향 프로그래밍 핵심인 클래스(Class) 개념을 기초부터 차근차근 알아봤어요.

단순한 구조부터 시작해서 메서드, 생성자, 상속, 오버라이딩까지 다양한 요소들을 배우면서 "클래스가 뭐지?"라는 질문에 명확한 답을 얻을 수 있었길 바랍니다 😊

이제 여러분은 파이썬으로 반복적인 작업을 자동화하고, 유연한 프로그램을 만들 수 있는 구조적 사고를 갖췄다고 할 수 있어요.

그리고 이 클래스 개념은 웹 개발, 게임 제작, 인공지능, 데이터 처리 등 어디서든 활용된답니다!

클래스는 단순히 문법이 아니라, 효율적인 사고방식이에요.

객체 단위로 세상을 바라보는 연습을 계속해 나가면, 분명 더 멋진 프로그램을 만들 수 있을 거예요.

 

다음에는 클래스 기반으로 더 복잡한 구조나 실제 프로젝트에 적용하는 방법을 함께 알아보도록 할게요! ✨

💬 오늘 내용 요약

  • 클래스와 객체는 설계도와 실체의 관계다
  • 메서드는 객체 동작의 정의, self는 자기 자신을 가리킨다
  • __init__ 생성자를 사용하면 객체 초기화를 자동화할 수 있다
  • 객체 변수는 서로 독립적으로 존재한다
  • 상속을 통해 코드 재사용과 기능 확장이 가능하다
  • 오버라이딩으로 부모 메서드의 기능을 재정의할 수 있다

읽어주셔서 감사합니다!

파이썬 클래스에 대해 더 궁금한 점이 있다면 언제든지 댓글로 질문해주세요 💬

 

다음 포스팅에서는 클래스 응용, 모듈화, 또는 간단한 프로젝트 구현 예제도 다뤄볼게요 🚀

반응형