콘텐츠로 이동

03. 클래스 상속과 추상화 (족보의 힘)

1. 상속 (Inheritance) - 족보 만들기

이미 잘 만들어진 클래스(부모)가 있다면, 코드를 복사&붙여넣기 하지 마세요. 상속을 받으면 부모의 모든 기능(변수, 메서드)을 내 것처럼 쓸 수 있습니다.

  • 부모 클래스 (Parent): 사람 (Person)
  • 자식 클래스 (Child): 학생 (Student), 선생님 (Teacher)
# 부모: 학교 구성원 (사람)
class Person:
    def __init__(self, name):
        self.name = name

    def introduce(self):
        print(f"안녕하세요, 저는 {self.name}입니다.")

# 자식: 학생 (Person을 상속받음)
class Student(Person):
    def study(self):
        print(f"{self.name}이(가) 열심히 공부를 합니다.")

# 자식: 선생님 (Person을 상속받음)
class Teacher(Person):
    def teach(self):
        print(f"{self.name} 선생님이 수업을 합니다.")

사용하기:

s = Student("지민")
s.introduce()  # 부모 뭐야 내 거! -> "안녕하세요, 저는 지민입니다."
s.study()      # 내 거! -> "지민이(가) 열심히 공부를 합니다."

2. 오버라이딩 (Overriding) - 청출어람

부모가 물려준 기능이 마음에 안 들면 내 입맛대로 바꿔버릴 수 있습니다. 이것을 메서드 오버라이딩(덮어쓰기)이라고 합니다.

class Student(Person):
    # 부모의 introduce를 무시하고 새로 정의!
    def introduce(self):
        print(f"저는 {self.name}이고, 파이썬을 공부 중입니다!")

class Teacher(Person):
    def introduce(self):
        print(f"반갑습니다. 저는 {self.name} 선생입니다.")

3. super() - 부모님 소환

내 마음대로 바꾸긴(오버라이딩) 했지만, 부모님의 원래 기능도 쓰고 싶을 때가 있습니다. 이때 super()를 사용합니다.

class LeaderStudent(Student):
    def introduce(self):
        super().introduce()  # 1. 부모(Student)의 introduce 먼저 실행
        print("그리고 저는 이 반의 반장입니다!")  # 2. 내 기능 추가

4. 추상 클래스 (Abstract Class) - 미완성 설계도

"'학교 구성원'이라는 건 개념일 뿐입니다. 실제로 학교에 다니는 건 '학생' 아니면 '선생님'이죠."

추상 클래스"자식들아, 이 메서드는 무조건 만들어야 해!" 라고 강제하는 역할을 합니다. 자신은 미완성이라서 인스턴스를 만들 수 없습니다. (abc 모듈 필요)

from abc import ABC, abstractmethod

# ABC(Abstract Base Class)를 상속받으면 추상 클래스가 됨
class SchoolMember(ABC):
    @abstractmethod
    def role(self):
        pass  # "자식들아, 너희 역할(role)은 너희가 각자 알아서 구현해라"

# Error! 추상 클래스는 생성 불가
# m = SchoolMember() 

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

    # 🌟 이걸 구현 안 하면 Student도 생성 불가 에러 남!
    def role(self):
        print(f"{self.name}: 저는 공부를 합니다.")

class Teacher(SchoolMember):
    def __init__(self, name):
        self.name = name

    def role(self):
        print(f"{self.name}: 저는 가르칩니다.")

🧠 멘탈 모델: 인터페이스(규격)

추상 클래스는 "USB 포트" 같은 규격입니다. 학생이든 선생님이든, "학교 구성원이라면 역할(role)이 있어야 한다"는 규격을 맞추는 것입니다.

classDiagram
    class SchoolMember {
        <<Abstract>>
        +role()*
    }
    class Student {
        +name
        +role()
    }
    class Teacher {
        +name
        +role()
    }
    SchoolMember <|-- Student : 상속 & 구현
    SchoolMember <|-- Teacher : 상속 & 구현

AI와 협업 포인트: 인터페이스 설계

복잡한 시스템을 만들 때는 AI에게 세부 구현보다 "추상 클래스 설계"를 먼저 시키세요.

> **프롬프트 예시:**
> "학교 관리 시스템을 만들 거야. 
> 모든 구성원이 가져야 할 공통 기능(출근/등교, 역할수행)을 
> 추상 클래스로 정의해줘."