SKN Family AI Bootcamp 24기 / 1주차 - Python (4)

A.·2026년 1월 31일

SKN 24

목록 보기
6/15

클래스 (Class)란?

클래스 = 객체(object)를 만들기 위한 설계도 또는 틀.

비유:
붕어빵 틀 = 클래스
붕어빵 = 객체 (인스턴스)

클래스는 속성과 동작을 정의한다.
객체(object/instance): 클래스를 바탕으로 메모리에 실제로 생성된 데이터.

어떤 규약이나 틀..프로그래밍에서 규약의 역할을 하는게 클래스.
(어떤 대상을 추상화하여 표현해서 나타내는 것)
규약을 통해 만들어낸 실제 형태 - 객체 (object)

클래스가 필요한 이유?

클래스 없이 코딩을 하면,

# 학생 1
student1_name = "김철수"
student1_age = 20
student1_major = "컴퓨터공학"

# 학생 2
student2_name = "이영희"
student2_age = 21
student2_major = "경영학"

# 학생 3
student3_name = "박민수"
student3_age = 19
student3_major = "수학"

# 😱 학생이 100명이면...?
  • 변수가 너무 많아짐
  • 관리가 어려움
  • 코드 재사용 불가

클래스 사용 시:

class Student:
    def __init__(self, name, age, major):
        self.name = name
        self.age = age
        self.major = major

# 객체 생성 (훨씬 간단!)
student1 = Student("김철수", 20, "컴퓨터공학")
student2 = Student("이영희", 21, "경영학")
student3 = Student("박민수", 19, "수학")

print(student1.name)  # 김철수
print(student2.age)   # 21

클래스의 기본 구조

  • 가장 간단한 클래스
class Dog:
    pass  # 아무것도 없는 빈 클래스

# 객체 생성
my_dog = Dog()
  • 속성(Attribute)이 있는 클래스
class Dog:
    # 생성자 (객체가 만들어질 때 자동 실행)
    def __init__(self, name, age):
        self.name = name  # 속성
        self.age = age    # 속성

# 객체 생성
dog1 = Dog("멍멍이", 3)
dog2 = Dog("바둑이", 5)

print(dog1.name)  # 멍멍이
print(dog2.age)   # 5

Dog: 클래스
dog1, dog2: 객체 인스턴스 (실제 만들어진 것)
name, age: 속성 (객체가 가진 데이터)
init: 생성자 (초기화 함수)
self: 자기자신을 가리키는 키워드

self

== 나 자신을 가리키는 특별한 변수

class Dog:
    def __init__(self, name):
        self.name = name  # self.name = 이 객체의 name
        
dog1 = Dog("멍멍이")
dog2 = Dog("바둑이")

# dog1.name → dog1의 name
# dog2.name → dog2의 name

비유:

# "내 이름은 ___입니다" 라고 할 때
# 철수가 말하면: "내(self) 이름은 철수입니다"
# 영희가 말하면: "내(self) 이름은 영희입니다"

규칙:

  • 메서드의 첫번째 파라미터는 항상 self
  • 객체 호출 시 self는 자동으로 전달됨 (직접 쓰지 않음)
class Dog:
    def bark(self):
        print(f"{self.name}이 짖습니다!")

dog = Dog("멍멍이")
dog.bark()  # self는 자동으로 dog를 가리킴

메서드 (Method)

메서드 = 클래스 안에 정의된 함수 (객체가 할수 있는 동작)

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    # 메서드 1: 짖기
    def bark(self):
        print(f"{self.name}: 멍멍!")
    
    # 메서드 2: 정보 출력
    def info(self):
        print(f"이름: {self.name}, 나이: {self.age}살")
    
    # 메서드 3: 나이 먹기
    def birthday(self):
        self.age += 1
        print(f"{self.name}이 {self.age}살이 되었습니다!")

# 사용
dog = Dog("멍멍이", 3)
dog.bark()      # 멍멍이: 멍멍!
dog.info()      # 이름: 멍멍이, 나이: 3살
dog.birthday()  # 멍멍이가 4살이 되었습니다!

생성자 (init)

생성자 = 객체가 만들어질 때 자동으로 실행되는 특별한 메서드

class Car:
    def __init__(self, brand, color):
        print("자동차가 만들어졌습니다!")
        self.brand = brand
        self.color = color

car = Car("현대", "빨강")
# 출력: 자동차가 만들어졌습니다!

기본값 설정

class Car:
    def __init__(self, brand, color="흰색"):
        self.brand = brand
        self.color = color

car1 = Car("현대")           # 색상 기본값 사용
car2 = Car("기아", "검정")   # 색상 직접 지정

print(car1.color)  # 흰색
print(car2.color)  # 검정

클래스 변수 (Class Variable) vs 인스턴스 변수 (Instance Variable)

클래스변수: 모든 객체가 공유

  • 우리 모두의 공통정보 (Species = "Human")
  • 해당 클래스로 생성된 모든 객체가 공유하는 속성
  • 메모리 공간 하나만 차지, 모든 인스턴스가 동일한 값 참조
  • 클래스 내부, 메서드외부에 선언
  • 클래스 이름.변수명 또는 인스턴스 이름.변수명 둘다 가능
class Dog:
    species = "포유류"  # 클래스 변수 (모든 개가 공유)
    
    def __init__(self, name):
        self.name = name  # 인스턴스 변수

dog1 = Dog("멍멍이")
dog2 = Dog("바둑이")

print(dog1.species)  # 포유류
print(dog2.species)  # 포유류 (같음!)
print(Dog.species)   # 포유류 (클래스로 직접 접근)

# 클래스 변수 변경
Dog.species = "동물"
print(dog1.species)  # 동물 (모두 바뀜!)

비유:

  • 클래스 변수 = 학교 이름 (모든 학생이 같음)
  • 인스턴스 변수 = 학생 이름 (각자 다름)

인스턴스 변수: 각 객체마다 다름

  • 나만의 고유한 정보 (self.name)
  • 각각의 객체가 개별적으로 가지는 속성
  • 객체마다 값이 다를 수 있음
  • init 메서드 안에서 self 변수명 형태로 선언
  • 인스턴스 이름.변수명으로 접근
class Dog:
    def __init__(self, name):
        self.name = name  # 인스턴스 변수

dog1 = Dog("멍멍이")
dog2 = Dog("바둑이")

print(dog1.name)  # 멍멍이
print(dog2.name)  # 바둑이 (다름!)

Private 속성 (캡슐화)

캡슐화 = 외부에서 직접 접근하지 못하게 숨기기

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner
        self.__balance = balance  # __(언더스코어 2개) = private
    
    def deposit(self, amount):
        self.__balance += amount
    
    def get_balance(self):  # Getter
        return self.__balance
    
    def set_balance(self, balance):  # Setter
        if balance >= 0:
            self.__balance = balance

account = BankAccount("철수", 10000)

# print(account.__balance)  # 에러! 직접 접근 불가
print(account.get_balance())  # 10000 (메서드로만 접근)

왜 숨길까?

잘못된 값이 들어가는 것 방지
데이터 보호
내부 구현을 숨겨서 변경에 유연

상속 (Inheritance)

상속 = 부모 클래스의 속성과 메서드를 물려받기

# 부모 클래스
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        print("동물이 소리를 냅니다")

# 자식 클래스
class Dog(Animal):  # Animal을 상속
    def speak(self):  # 메서드 오버라이딩 (재정의)
        print(f"{self.name}: 멍멍!")

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

# 사용
dog = Dog("멍멍이")
cat = Cat("나비")

dog.speak()  # 멍멍이: 멍멍!
cat.speak()  # 나비: 야옹~

부모 메서드 호출 (super)

class Animal:
    def __init__(self, name):
        self.name = name
        print(f"{name}이(가) 태어났습니다!")

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 부모의 __init__ 호출
        self.breed = breed
        print(f"견종: {breed}")

dog = Dog("멍멍이", "진돗개")
# 출력:
# 멍멍이이(가) 태어났습니다!
# 견종: 진돗개

매직메서드 (Magic Methods)

특별메서드=''로 시작하고 끝나는 특별한 기능을 가진 메서드
str__ (문자열 표현)

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"강아지(이름: {self.name}, 나이: {self.age}살)"

dog = Dog("멍멍이", 3)
print(dog)  # 강아지(이름: 멍멍이, 나이: 3살)

len(길이)

class Playlist:
    def __init__(self):
        self.songs = []
    
    def add(self, song):
        self.songs.append(song)
    
    def __len__(self):
        return len(self.songs)

playlist = Playlist()
playlist.add("노래1")
playlist.add("노래2")

print(len(playlist))  # 2

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)
p3 = p1 + p2  # __add__ 호출

print(p3)  # (4, 6)
# 클래스 = 설계도
class Dog:
    # 클래스 변수 (모두 공유)
    species = "포유류"
    
    # 생성자 (초기화)
    def __init__(self, name, age):
        self.name = name    # 인스턴스 변수
        self.age = age
    
    # 메서드 (기능)
    def bark(self):
        return f"{self.name}: 멍멍!"
    
    # 특별 메서드
    def __str__(self):
        return f"Dog({self.name}, {self.age}살)"

# 객체 = 실제 만들어진 것
dog1 = Dog("멍멍이", 3)
dog2 = Dog("바둑이", 5)

다형성 (Polymorphism) 개요와 예시

정의

다형성 = 하나의 인터페이스로 여러 형태의 구현을 다루는 것

  1. 같은 메서드 이름이 객체에 따라 다르게 동작
    (같은 멤버 함수 호출에 대해 다른 클래스의 인스턴스들이 각각 다르게 반응)
    쉽게 말하면,
    같은 명령어인데, 누구한테 시키느냐에 따라 다르게 행동함.

예시

class Dog:
    def 소리내(self):
        print("멍멍!")

class Cat:
    def 소리내(self):
        print("야옹~")

class Cow:
    def 소리내(self):
        print("음메~")

# 같은 명령어 "소리내()"
강아지 = Dog()
고양이 = Cat()
소 = Cow()

강아지.소리내()  # 멍멍!
고양이.소리내()  # 야옹~
소.소리내()      # 음메~

명령어는 똑같이 .소리내()
하지만 누구한테 시키느냐에 따라 결과 달라짐

  1. 상속관계가 없어도 적용 가능
    부모-자식 관계가 아니어도 같은 이름의 메서드만 있으면 됨.

eg)상속 없이도 작동

# 상속 관계 전혀 없음!
class 자동차:
    def 출발(self):
        print("🚗 부릉부릉 출발!")

class 비행기:
    def 출발(self):
        print("✈️ 이륙합니다!")

class 배:
    def 출발(self):
        print("⛵ 닻을 올립니다!")

# 모두 '출발()' 메서드만 있으면 작동
탈것들 = [자동차(), 비행기(), 배()]

for 탈것 in 탈것들:
    탈것.출발()  # 다형성!

# 출력:
# 🚗 부릉부릉 출발!
# ✈️ 이륙합니다!
# ⛵ 닻을 올립니다!

-> 자동차, 비행기, 배는 서로 관계 없음
-> 하지만 모두 출발() 메서드가 있으니까 같은 방식으로 처리가능.

  1. 파이썬에서는 다형성을 적용하기가 쉬움
    즉, 타입을 미리 정하지 않아서 더 자유롭다.

  2. 실시간 결정
    실행할 때 알아서 판단

  3. 연산자도 다형성

1 + 2 = 3 (숫자 더하기)
"a" + "b" = "ab" (문자 연결)
같은 + 인데 다르게 동작!

💡 실생활 비유

비유 1: 리모컨

TV 리모컨 전원 버튼 → TV 켜짐
에어컨 리모컨 전원 버튼 → 에어컨 켜짐
선풍기 리모컨 전원 버튼 → 선풍기 켜짐

같은 "전원 버튼"인데 기기마다 다르게 동작!

비유 2: "가져와!"

강아지한테 "가져와!" → 공 물어옴
고양이한테 "가져와!" → 무시함
사람한테 "가져와!" → 손으로 가져옴

같은 명령인데 누구한테 하느냐에 따라 다름!

다형성 = 똑같은 이름, 다른 동작

# 핵심 코드
animals = [Dog(), Cat(), Cow()]

for animal in animals:
    animal.speak()  # 같은 speak()인데...
    
# 결과:
# 멍멍!  ← Dog의 speak()
# 야옹~  ← Cat의 speak()
# 음메~  ← Cow의 speak()
profile
코린이

0개의 댓글