Skip to Content
💻 코리아IT아카데미 신촌 - 프로그래밍 학습 자료

Topic 6: 상속 기초 - 클래스의 확장 🌱

🎯 학습 목표

상속의 기본 개념을 이해하고, 부모 클래스로부터 자식 클래스를 만들어 코드를 재사용하고 기능을 확장할 수 있습니다.

🧬 상속(Inheritance)이란?

일상생활의 상속

실생활 비유:

  • 부모 → 자식: 외모, 성격, 능력을 물려받음
  • 자동차 → 스포츠카: 기본 기능 + 추가 기능
  • 스마트폰 → 게이밍폰: 기본 기능 + 게임 특화 기능

프로그래밍에서의 상속

상속은 기존 클래스(부모)의 속성과 메서드를 새로운 클래스(자식)가 물려받는 것입니다.

# 부모 클래스 (기본 동물) class Animal: def __init__(self, name): self.name = name self.energy = 100 def eat(self): self.energy += 20 print(f"{self.name}가 먹이를 먹습니다. 에너지: {self.energy}") def sleep(self): self.energy += 30 print(f"{self.name}가 잠을 잡니다. 에너지: {self.energy}") # 자식 클래스 (강아지 - Animal을 상속) class Dog(Animal): # Animal 클래스를 상속받음 def bark(self): # 강아지만의 고유 기능 print(f"{self.name}가 멍멍 짖습니다!") # 자식 클래스 (고양이 - Animal을 상속) class Cat(Animal): # Animal 클래스를 상속받음 def meow(self): # 고양이만의 고유 기능 print(f"{self.name}가 야옹 웁니다!") # 강아지와 고양이는 Animal의 기능을 모두 사용 가능 dog = Dog("뽀삐") cat = Cat("나비") # 부모 클래스의 메서드 사용 dog.eat() # 뽀삐가 먹이를 먹습니다. 에너지: 120 dog.sleep() # 뽀삐가 잠을 잡니다. 에너지: 150 # 자식 클래스의 고유 메서드 사용 dog.bark() # 뽀삐가 멍멍 짖습니다! cat.meow() # 나비가 야옹 웁니다!

👨‍👩‍👧‍👦 상속의 기본 문법

기본 상속 구조

class 부모클래스: # 부모의 속성과 메서드 class 자식클래스(부모클래스): # 부모의 모든 기능 + 자식만의 추가 기능

실용적인 예시: 사람과 직업

class Person: """기본 사람 클래스""" def __init__(self, name, age): self.name = name self.age = age self.energy = 100 def introduce(self): print(f"안녕하세요! 저는 {self.name}이고, {self.age}세입니다.") def eat(self): self.energy += 20 print(f"{self.name}가 식사를 했습니다. 에너지: {self.energy}") def rest(self): self.energy += 30 print(f"{self.name}가 휴식을 취했습니다. 에너지: {self.energy}") class Student(Person): """학생 클래스 - Person을 상속""" def __init__(self, name, age, grade): super().__init__(name, age) # 부모 클래스의 __init__ 호출 self.grade = grade self.score = 0 def study(self): self.energy -= 20 self.score += 10 print(f"{self.name}가 공부했습니다! 점수: {self.score}, 에너지: {self.energy}") def take_exam(self): if self.energy >= 30: self.energy -= 30 exam_score = min(100, self.score + 20) print(f"{self.name}의 시험 점수: {exam_score}점") return exam_score else: print(f"{self.name}는 너무 피곤해서 시험을 볼 수 없습니다!") return 0 class Teacher(Person): """선생님 클래스 - Person을 상속""" def __init__(self, name, age, subject): super().__init__(name, age) # 부모 클래스의 __init__ 호출 self.subject = subject self.students = [] def teach(self): self.energy -= 15 print(f"{self.name} 선생님이 {self.subject}를 가르칩니다! 에너지: {self.energy}") def add_student(self, student_name): self.students.append(student_name) print(f"{student_name} 학생이 {self.name} 선생님의 수업에 등록되었습니다!") # 사람들 생성 student = Student("kim_cheolsu", 16, 2) teacher = Teacher("lee_younghee", 35, "수학") # 모든 사람이 할 수 있는 행동 (상속받은 기능) student.introduce() # 안녕하세요! 저는 kim_cheolsu이고, 16세입니다. teacher.introduce() # 안녕하세요! 저는 lee_younghee이고, 35세입니다. student.eat() # kim_cheolsu가 식사를 했습니다. teacher.rest() # lee_younghee가 휴식을 취했습니다. # 각자만의 고유한 행동 student.study() # kim_cheolsu가 공부했습니다! student.take_exam() # kim_cheolsu의 시험 점수: 30점 teacher.teach() # lee_younghee 선생님이 수학를 가르칩니다! teacher.add_student("kim_cheolsu") # kim_cheolsu 학생이 lee_younghee 선생님의 수업에 등록되었습니다!

🔧 super() 함수

super()의 역할

super()는 부모 클래스의 메서드를 호출할 때 사용하는 특별한 함수입니다.

class Vehicle: """탈것 기본 클래스""" def __init__(self, brand, model, year): self.brand = brand self.model = model self.year = year self.speed = 0 self.fuel = 100 def start_engine(self): print(f"{self.brand} {self.model}의 엔진이 시작됩니다!") def accelerate(self, amount): self.speed += amount self.fuel -= amount * 0.1 print(f"가속! 현재 속도: {self.speed}km/h, 연료: {self.fuel:.1f}%") def stop(self): self.speed = 0 print(f"{self.brand} {self.model}이 정지했습니다.") class Car(Vehicle): """자동차 클래스""" def __init__(self, brand, model, year, doors): super().__init__(brand, model, year) # 부모의 __init__ 호출 self.doors = doors # 자동차만의 추가 속성 def open_door(self): print(f"{self.doors}개 문 중 하나를 열었습니다.") def honk(self): print("빵빵! 경적을 울립니다!") class Motorcycle(Vehicle): """오토바이 클래스""" def __init__(self, brand, model, year, engine_size): super().__init__(brand, model, year) # 부모의 __init__ 호출 self.engine_size = engine_size # 오토바이만의 추가 속성 def wheelie(self): if self.speed > 30: print("앞바퀴 들기 묘기를 부립니다! 🏍️") else: print("더 빠른 속도가 필요합니다!") # 다양한 탈것들 my_car = Car("현대", "소나타", 2023, 4) my_motorcycle = Motorcycle("혼다", "CBR", 2022, 600) # 공통 기능들 (상속받은 기능) my_car.start_engine() # 현대 소나타의 엔진이 시작됩니다! my_car.accelerate(50) # 가속! 현재 속도: 50km/h my_car.open_door() # 4개 문 중 하나를 열었습니다. my_car.honk() # 빵빵! 경적을 울립니다! my_motorcycle.start_engine() # 혼다 CBR의 엔진이 시작됩니다! my_motorcycle.accelerate(40) # 가속! 현재 속도: 40km/h my_motorcycle.wheelie() # 앞바퀴 들기 묘기를 부립니다! 🏍️

🎭 메서드 오버라이딩(Method Overriding)

부모의 메서드를 자식이 다시 정의

class Animal: def __init__(self, name, species): self.name = name self.species = species def make_sound(self): print(f"{self.name}가 소리를 냅니다.") def move(self): print(f"{self.name}가 움직입니다.") def introduce(self): print(f"저는 {self.species} {self.name}입니다.") class Dog(Animal): def __init__(self, name, breed): super().__init__(name, "강아지") # species를 "강아지"로 고정 self.breed = breed def make_sound(self): # 메서드 오버라이딩 print(f"{self.name}가 멍멍 짖습니다!") def move(self): # 메서드 오버라이딩 print(f"{self.name}가 꼬리를 흔들며 뛰어갑니다!") def fetch(self): # 강아지만의 고유 메서드 print(f"{self.name}가 공을 가져옵니다!") class Cat(Animal): def __init__(self, name, color): super().__init__(name, "고양이") # species를 "고양이"로 고정 self.color = color def make_sound(self): # 메서드 오버라이딩 print(f"{self.name}가 야옹 웁니다!") def move(self): # 메서드 오버라이딩 print(f"{self.name}가 우아하게 걸어갑니다!") def climb(self): # 고양이만의 고유 메서드 print(f"{self.name}가 높은 곳으로 올라갑니다!") class Bird(Animal): def __init__(self, name, wing_span): super().__init__(name, "새") self.wing_span = wing_span def make_sound(self): # 메서드 오버라이딩 print(f"{self.name}가 짹짹 웁니다!") def move(self): # 메서드 오버라이딩 print(f"{self.name}가 날개를 펼쳐 하늘을 날아갑니다!") def fly(self): # 새만의 고유 메서드 print(f"{self.name}{self.wing_span}cm 날개를 펼치고 비행합니다!") # 다양한 동물들 dog = Dog("뽀삐", "골든리트리버") cat = Cat("나비", "흰색") = Bird("피피", 25) print("=== 자기소개 ===") dog.introduce() # 저는 강아지 뽀삐입니다. cat.introduce() # 저는 고양이 나비입니다. 새.introduce() # 저는 새 피피입니다. print("\n=== 소리내기 ===") dog.make_sound() # 뽀삐가 멍멍 짖습니다! cat.make_sound() # 나비가 야옹 웁니다! 새.make_sound() # 피피가 짹짹 웁니다! print("\n=== 움직이기 ===") dog.move() # 뽀삐가 꼬리를 흔들며 뛰어갑니다! cat.move() # 나비가 우아하게 걸어갑니다! 새.move() # 피피가 날개를 펼쳐 하늘을 날아갑니다! print("\n=== 고유 행동 ===") dog.fetch() # 뽀삐가 공을 가져옵니다! cat.climb() # 나비가 높은 곳으로 올라갑니다! 새.fly() # 피피가 25cm 날개를 펼치고 비행합니다!

🎮 실전 예시: 게임 캐릭터 시스템

class GameCharacter: """게임 캐릭터 기본 클래스""" def __init__(self, name, level=1): self.name = name self.level = level self.hp = 100 self.max_hp = 100 self.experience = 0 def attack(self, target): damage = self.calculate_damage() print(f"{self.name}{target}에게 {damage} 데미지를 입혔습니다!") return damage def calculate_damage(self): return 10 + self.level * 2 def level_up(self): self.level += 1 self.max_hp += 20 self.hp = self.max_hp print(f"🎉 {self.name}가 레벨업! Lv.{self.level}") def show_status(self): print(f"=== {self.name} 상태 ===") print(f"레벨: {self.level}") print(f"HP: {self.hp}/{self.max_hp}") print(f"경험치: {self.experience}") class Warrior(GameCharacter): """전사 클래스""" def __init__(self, name, level=1): super().__init__(name, level) self.hp = 150 # 전사는 체력이 더 많음 self.max_hp = 150 self.armor = 10 def calculate_damage(self): # 전사는 더 강한 공격력 return 15 + self.level * 3 def shield_block(self): print(f"{self.name}가 방패로 공격을 막습니다! 🛡️") return self.armor def berserker_mode(self): print(f"{self.name}가 광전사 모드 발동! 🔥") return self.calculate_damage() * 2 class Mage(GameCharacter): """마법사 클래스""" def __init__(self, name, level=1): super().__init__(name, level) self.hp = 80 # 마법사는 체력이 적음 self.max_hp = 80 self.mana = 100 self.max_mana = 100 def calculate_damage(self): # 마법사는 마나 기반 공격 return 12 + self.level * 4 def cast_spell(self, spell_name): if self.mana >= 20: self.mana -= 20 damage = self.calculate_damage() * 1.5 print(f"{self.name}{spell_name} 마법을 시전! ✨ 데미지: {damage}") return damage else: print(f"{self.name}의 마나가 부족합니다!") return 0 def meditate(self): self.mana = min(self.max_mana, self.mana + 30) print(f"{self.name}가 명상으로 마나를 회복합니다. 마나: {self.mana}") def show_status(self): super().show_status() # 부모의 show_status 호출 print(f"마나: {self.mana}/{self.max_mana}") # 마법사만의 추가 정보 class Archer(GameCharacter): """궁수 클래스""" def __init__(self, name, level=1): super().__init__(name, level) self.arrows = 50 self.accuracy = 0.8 def calculate_damage(self): # 궁수는 정확도 기반 공격 base_damage = 8 + self.level * 2 if self.accuracy > 0.7: return int(base_damage * 1.3) # 높은 정확도 보너스 return base_damage def shoot_arrow(self, target): if self.arrows > 0: self.arrows -= 1 damage = self.calculate_damage() print(f"{self.name}{target}에게 화살을 발사! 🏹 데미지: {damage}") print(f"남은 화살: {self.arrows}발") return damage else: print(f"{self.name}의 화살이 떨어졌습니다!") return 0 def reload_arrows(self): self.arrows = 50 print(f"{self.name}가 화살을 다시 장전했습니다! 🏹") def show_status(self): super().show_status() # 부모의 show_status 호출 print(f"화살: {self.arrows}발") # 궁수만의 추가 정보 print(f"정확도: {self.accuracy*100:.0f}%") # 다양한 캐릭터들 생성 warrior = Warrior("드래곤슬레이어", 5) mage = Mage("아이스퀸", 4) archer = Archer("로빈후드", 3) print("=== 캐릭터 상태 ===") warrior.show_status() print() mage.show_status() print() archer.show_status() print("\n=== 전투 시뮬레이션 ===") warrior.attack("오크") warrior.berserker_mode() mage.cast_spell("파이어볼") mage.meditate() archer.shoot_arrow("슬라임") archer.shoot_arrow("고블린")

🔍 isinstance()와 상속

상속 관계 확인하기

class Animal: pass class Dog(Animal): pass class Cat(Animal): pass # 객체들 생성 dog = Dog() cat = Cat() # isinstance로 상속 관계 확인 print(f"강아지는 Dog? {isinstance(dog, Dog)}") # True print(f"강아지는 Animal? {isinstance(dog, Animal)}") # True print(f"강아지는 Cat? {isinstance(dog, Cat)}") # False print(f"고양이는 Cat? {isinstance(cat, Cat)}") # True print(f"고양이는 Animal? {isinstance(cat, Animal)}") # True print(f"고양이는 Dog? {isinstance(cat, Dog)}") # False

🚨 자주 발생하는 오류

오류 1: super() 호출 누락

class Person: def __init__(self, name, age): self.name = name self.age = age class Student(Person): def __init__(self, name, age, grade): # ❌ super() 호출 누락 # self.name = name # self.age = age # 부모의 초기화가 누락됨! # ✅ 올바른 방법 super().__init__(name, age) self.grade = grade

오류 2: 메서드 오버라이딩 실수

class Animal: def make_sound(self): print("동물이 소리를 냅니다") class Dog(Animal): # ❌ 메서드 이름 실수 # def make_sounds(self): # 's' 추가로 다른 메서드가 됨 # print("멍멍!") # ✅ 정확한 메서드 이름 def make_sound(self): print("멍멍!")

💡 퀴즈: 상속 기초 이해도 체크

Q1. 상속에서 자식 클래스가 할 수 있는 것은?

  1. 부모 클래스의 속성과 메서드 사용
  2. 새로운 속성과 메서드 추가
  3. 부모 클래스의 메서드 오버라이딩
  4. 위의 모든 것

💡 정답 확인

정답: 4번 (위의 모든 것)

자식 클래스는 부모의 모든 기능을 사용할 수 있고, 새로운 기능을 추가하거나 기존 기능을 재정의할 수 있습니다.

Q2. super()의 역할은?

  1. 자식 클래스를 호출한다
  2. 부모 클래스의 메서드를 호출한다
  3. 새로운 클래스를 생성한다
  4. 클래스를 삭제한다

💡 정답 확인

정답: 2번 (부모 클래스의 메서드를 호출한다)

super()는 자식 클래스에서 부모 클래스의 메서드를 호출할 때 사용합니다.

Q3. 다음 코드에서 결과는?

class Animal: def speak(self): return "동물이 소리를 냅니다" class Dog(Animal): def speak(self): return "멍멍!" dog = Dog() print(dog.speak())
  1. “동물이 소리를 냅니다”
  2. “멍멍!”
  3. 오류 발생
  4. 아무것도 출력되지 않음

💡 정답 확인

정답: 2번 (“멍멍!”)

자식 클래스의 speak() 메서드가 부모 클래스의 메서드를 오버라이딩했기 때문에 자식 클래스의 메서드가 실행됩니다.

✅ 상속 기초 마스터 체크리스트

✅ 상속 기초 마스터 체크리스트

🎊 Unit 6 완주!

상속까지 학습하면서 객체지향 프로그래밍의 핵심을 모두 마스터했습니다!

🏆 Unit 6에서 배운 내용

  1. 클래스 기본: 클래스와 객체의 개념, 객체 생성
  2. 속성과 메서드: 객체의 정보와 행동 구현
  3. 생성자와 초기화: 매개변수로 객체 초기화
  4. 클래스 활용: 실전 프로젝트에서 클래스 활용
  5. 고급 기능: 클래스 변수, 정적 메서드, 특수 메서드
  6. 상속: 코드 재사용과 클래스 확장

🚀 이제 할 수 있는 것들

  • 객체지향적 사고: 현실 세계를 클래스와 객체로 모델링
  • 코드 재사용: 상속을 통한 효율적인 코드 작성
  • 복잡한 시스템 설계: 여러 클래스가 협력하는 프로그램
  • 실전 프로젝트: 게임, 은행 시스템, 쇼핑몰 등 구현

🌟 객체지향 프로그래밍의 핵심 원칙

  1. 캡슐화: 관련된 데이터와 기능을 클래스로 묶기
  2. 상속: 기존 클래스를 확장하여 새로운 클래스 만들기
  3. 다형성: 같은 인터페이스로 다른 동작 구현
  4. 추상화: 복잡한 내부 구조를 숨기고 필요한 기능만 제공

축하합니다! 이제 여러분은 파이썬 객체지향 프로그래밍의 기초를 완전히 마스터했습니다! 🎊

클래스와 상속을 활용하여 더욱 구조적이고 재사용 가능한 코드를 작성할 수 있습니다. 이는 큰 프로젝트를 개발할 때 매우 중요한 기술입니다! 🚀

Last updated on