파이썬 객체지향 프로그래밍 실전 예제 20개

클래스, 객체, 생성자, 상속, 다형성, 캡슐화까지 한 번에 정리하는 학교 제출용 HTML 자료
학습 포인트
기초

1. 클래스와 객체 만들기

핵심 개념: 클래스를 정의하고 객체를 생성하는 가장 기본적인 형태입니다.
예시 코드
class Dog:
    pass

d = Dog()
print(type(d))
예상 결과:
<class '__main__.Dog'>
설명: Dog는 설계도이고, d는 그 설계도로 만든 객체(인스턴스)입니다.
기초

2. 생성자 __init__ 사용

핵심 개념: 객체가 만들어질 때 자동으로 속성을 초기화합니다.
예시 코드
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

s = Student("민수", 2)
print(s.name, s.grade)
예상 결과:
민수 2
설명: __init__은 객체 생성 직후 자동 실행되며, self.name처럼 인스턴스 속성을 저장합니다.
기초

3. 인스턴스 메서드 만들기

핵심 개념: 객체에 동작을 부여하는 메서드를 정의합니다.
예시 코드
class Calculator:
    def add(self, a, b):
        return a + b

c = Calculator()
print(c.add(3, 5))
예상 결과:
8
설명: 메서드는 반드시 첫 번째 매개변수로 self를 받아 현재 객체 자신을 가리킵니다.
기초

4. 객체 상태 출력하기

핵심 개념: __str__을 사용하면 객체를 print할 때 보기 좋은 문자열을 반환할 수 있습니다.
예시 코드
class Book:
    def __init__(self, title):
        self.title = title

    def __str__(self):
        return f"책 제목: {self.title}"

b = Book("파이썬 입문")
print(b)
예상 결과:
책 제목: 파이썬 입문
설명: __str__은 객체를 문자열처럼 표현할 때 자동 호출됩니다.
속성

5. 클래스 변수 사용

핵심 개념: 모든 객체가 공유하는 값을 클래스 변수로 만들 수 있습니다.
예시 코드
class Counter:
    count = 0

    def __init__(self):
        Counter.count += 1

a = Counter()
b = Counter()
print(Counter.count)
예상 결과:
2
설명: count는 클래스 전체가 공유하는 값이며, 객체마다 따로 생기지 않습니다.
속성

6. 인스턴스 변수와 클래스 변수 차이

핵심 개념: 공유 변수와 개별 변수를 함께 비교해 봅니다.
예시 코드
class Person:
    species = "human"

    def __init__(self, name):
        self.name = name

p1 = Person("철수")
p2 = Person("영희")
print(p1.species, p2.species)
print(p1.name, p2.name)
예상 결과:
human human
철수 영희
설명: species는 공유되고, name은 각 객체마다 따로 저장됩니다.
메서드

7. 클래스 메서드 @classmethod

핵심 개념: 클래스 자체를 다루는 메서드를 만들 수 있습니다.
예시 코드
class School:
    total = 0

    @classmethod
    def add_student(cls):
        cls.total += 1

School.add_student()
School.add_student()
print(School.total)
예상 결과:
2
설명: cls는 클래스 자신을 가리키며, 클래스 수준 데이터를 수정할 때 유용합니다.
메서드

8. 정적 메서드 @staticmethod

핵심 개념: 객체나 클래스 정보 없이 독립적으로 동작하는 함수를 클래스 안에 둘 수 있습니다.
예시 코드
class MathTool:
    @staticmethod
    def square(x):
        return x * x

print(MathTool.square(6))
예상 결과:
36
설명: 정적 메서드는 self나 cls를 받지 않으며, 기능상 관련된 함수를 묶을 때 좋습니다.
캡슐화

9. 비공개 속성 흉내내기

핵심 개념: 언더스코어 두 개를 사용해 직접 접근을 어렵게 만들 수 있습니다.
예시 코드
class Account:
    def __init__(self, money):
        self.__money = money

    def show(self):
        return self.__money

a = Account(5000)
print(a.show())
예상 결과:
5000
설명: __money는 이름 변경(name mangling)이 적용되어 외부 직접 접근을 어렵게 합니다.
캡슐화

10. getter / setter 스타일

핵심 개념: 메서드를 통해 값을 안전하게 읽고 수정합니다.
예시 코드
class Temperature:
    def __init__(self):
        self._c = 0

    def set_c(self, value):
        if value >= -273:
            self._c = value

    def get_c(self):
        return self._c

t = Temperature()
t.set_c(25)
print(t.get_c())
예상 결과:
25
설명: setter에서 조건 검사를 넣어 잘못된 값이 들어가지 않게 할 수 있습니다.
프로퍼티

11. @property 사용

핵심 개념: 메서드를 속성처럼 접근할 수 있게 만듭니다.
예시 코드
class Circle:
    def __init__(self, r):
        self.r = r

    @property
    def area(self):
        return 3.14 * self.r ** 2

c = Circle(3)
print(c.area)
예상 결과:
28.26
설명: area()처럼 호출하지 않고 c.area처럼 속성처럼 읽을 수 있습니다.
상속

12. 상속의 기본

핵심 개념: 기존 클래스를 물려받아 새로운 클래스를 만들 수 있습니다.
예시 코드
class Animal:
    def speak(self):
        return "소리를 낸다"

class Cat(Animal):
    pass

c = Cat()
print(c.speak())
예상 결과:
소리를 낸다
설명: Cat은 Animal의 메서드를 그대로 물려받습니다.
상속

13. 메서드 오버라이딩

핵심 개념: 상속받은 메서드를 자식 클래스에서 새롭게 정의할 수 있습니다.
예시 코드
class Animal:
    def speak(self):
        return "..."

class Cat(Animal):
    def speak(self):
        return "야옹"

print(Cat().speak())
예상 결과:
야옹
설명: 같은 이름의 메서드를 다시 정의하면 자식 클래스의 버전이 우선 사용됩니다.
상속

14. super()로 부모 생성자 호출

핵심 개념: 부모 클래스의 초기화 코드를 재사용할 수 있습니다.
예시 코드
class Person:
    def __init__(self, name):
        self.name = name

class Teacher(Person):
    def __init__(self, name, subject):
        super().__init__(name)
        self.subject = subject

t = Teacher("김선생", "수학")
print(t.name, t.subject)
예상 결과:
김선생 수학
설명: super().__init__()을 쓰면 부모 클래스의 초기화 로직을 그대로 활용할 수 있습니다.
다형성

15. 같은 메서드 이름, 다른 동작

핵심 개념: 서로 다른 객체가 같은 메서드 이름에 대해 다르게 반응할 수 있습니다.
예시 코드
class Dog:
    def speak(self):
        return "멍멍"

class Cat:
    def speak(self):
        return "야옹"

for animal in [Dog(), Cat()]:
    print(animal.speak())
예상 결과:
멍멍
야옹
설명: 둘 다 speak()를 가지고 있으므로, 같은 코드로 서로 다른 객체를 처리할 수 있습니다.
실전

16. 학생 성적 관리 클래스

핵심 개념: 리스트 속성을 가진 객체를 만들어 평균을 계산합니다.
예시 코드
class Student:
    def __init__(self, name):
        self.name = name
        self.scores = []

    def add_score(self, score):
        self.scores.append(score)

    def average(self):
        return sum(self.scores) / len(self.scores)

s = Student("지수")
s.add_score(90)
s.add_score(100)
print(s.average())
예상 결과:
95.0
설명: 객체 안에 리스트를 두면 관련 데이터를 하나로 묶어 관리하기 좋습니다.
실전

17. 은행 계좌 입출금

핵심 개념: 상태 변화가 있는 객체를 만들어 입금과 출금을 처리합니다.
예시 코드
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, money):
        self.balance += money

    def withdraw(self, money):
        if money <= self.balance:
            self.balance -= money

a = BankAccount("민호", 10000)
a.deposit(5000)
a.withdraw(3000)
print(a.balance)
예상 결과:
12000
설명: 객체는 현재 상태(balance)를 저장하고, 메서드로 그 상태를 변경합니다.
실전

18. 쇼핑카트 클래스

핵심 개념: 상품 목록을 담고 총합을 계산하는 객체를 만듭니다.
예시 코드
class Cart:
    def __init__(self):
        self.items = []

    def add(self, name, price):
        self.items.append((name, price))

    def total(self):
        return sum(price for _, price in self.items)

c = Cart()
c.add("노트", 2000)
c.add("펜", 1000)
print(c.total())
예상 결과:
3000
설명: 관련 데이터를 묶고 총합 계산 기능까지 제공하면 재사용성이 높은 객체가 됩니다.
실전

19. 게임 캐릭터 상속 구조

핵심 개념: 기본 캐릭터를 만들고 전사/마법사로 확장할 수 있습니다.
예시 코드
class Character:
    def __init__(self, name, hp):
        self.name = name
        self.hp = hp

class Warrior(Character):
    def attack(self):
        return "검 공격!"

class Wizard(Character):
    def attack(self):
        return "마법 공격!"

print(Warrior("아더", 100).attack())
print(Wizard("메린", 80).attack())
예상 결과:
검 공격!
마법 공격!
설명: 공통 속성(name, hp)은 부모에 두고, 직업별 행동은 자식에서 나눌 수 있습니다.
실전

20. 연산자 오버로딩 __add__

핵심 개념: 객체끼리 + 연산을 가능하게 할 수 있습니다.
예시 코드
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __str__(self):
        return f"({self.x}, {self.y})"

p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2)
예상 결과:
(4, 6)
설명: __add__를 정의하면 객체끼리 덧셈 연산의 의미를 직접 설계할 수 있습니다.