
안녕! 파이썬의 '다형성'이라는 마법에 대해 알려줄게. 좀 어려운 말 같지만, 아주 재미있는 마술 같은 거야!
다형성이 뭐냐고요?
음... '여러 가지 모양'이라는 뜻이야. 똑같은 이름을 불렀는데, 또는 똑같은 행동을 시켰는데, 누가 대답하느냐 또는 누가 행동하느냐에 따라 다른 결과가 나오는 거지!
예를 들어 볼까?
우리 반 친구들한테 "자기소개 해봐!" 라고 선생님이 말씀하셨다고 생각해 보자.
- 철수는 "안녕, 나는 축구를 좋아하는 철수야!" 라고 말할 거야.
- 영희는 "안녕, 나는 그림 그리기를 좋아하는 영희야!" 라고 말할 거야.
- 민준이는 "안녕, 나는 로봇 만들기를 좋아하는 민준이야!" 라고 말할 거야.
선생님은 똑같이 "자기소개 해봐!" 라고 말씀하셨지만, 철수, 영희, 민준이는 각자 다른 자기소개를 했지? 이렇게 똑같은 지시에도 서로 다른 행동이나 말을 하는 것을 '다형성'이라고 해.
더 쉬운 예! 동물 소리 흉내 내기!
동물 친구들이 있다고 상상해 봐. 이 동물 친구들은 모두 "소리내기"라는 특별한 재주를 가지고 있어.
- 강아지한테 "소리내봐!" 하면 "멍멍!" 하고 짖을 거야.
- 고양이한테 "소리내봐!" 하면 "야옹~" 하고 울겠지?
- 병아리한테 "소리내봐!" 하면 "삐약삐약!" 할 거야.
모두 똑같이 "소리내봐!" 라는 말을 듣지만, 강아지, 고양이, 병아리는 각자 다른 소리를 내지? 이게 바로 다형성이야!
파이썬 코드로 이 마법을 한번 볼까?
다형성을 보여주기 위해 동물 예제를 사용해 보겠습니다. 동물 예제가 다형성을 이해하는 데 더 직관적일 수 있습니다.
# 부모 클래스 Animal 정의
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
# 이 메서드는 자식 클래스에서 오버라이드(재정의)될 것을 기대합니다.
raise NotImplementedError("Subclass must implement abstract method")
# Animal 클래스를 상속받는 자식 클래스 Dog 정의
class Dog(Animal):
def speak(self):
return f"{self.name}(이)가 멍멍! 하고 짖습니다."
# Animal 클래스를 상속받는 자식 클래스 Cat 정의
class Cat(Animal):
def speak(self):
return f"{self.name}(이)가 야옹~ 하고 웁니다."
# Animal 클래스를 상속받는 자식 클래스 Cow 정의
class Cow(Animal):
def speak(self):
return f"{self.name}(이)가 음메~ 하고 웁니다."
# 다양한 동물 객체 생성
dog = Dog("바둑이")
cat = Cat("나비")
cow = Cow("얼룩이")
# 동물 객체들을 리스트에 담기
animals = [dog, cat, cow]
# 리스트를 순회하며 각 동물의 speak() 메서드 호출
print("다형성을 이용한 동물 소리 내기:")
for animal in animals:
# 같은 animal.speak() 호출이지만,
# 객체의 실제 타입(Dog, Cat, Cow)에 따라 다른 행동을 보입니다.
print(animal.speak())
print("\n--- 개별 객체 호출 ---")
print(dog.speak())
print(cat.speak())
print(cow.speak())
-----------2번예제----------------------
# Person/Student 예제로 다형성 보기 (간단한 형태)
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"{self.name}입니다. 안녕하세요!"
class Student(Person):
def __init__(self, name, student_id):
super().__init__(name)
self.student_id = student_id
# 부모 클래스의 greet 메서드를 오버라이드 (재정의)
def greet(self):
return f"저는 학생 {self.name}이고, 학번은 {self.student_id}입니다. 반갑습니다!"
person1 = Person("김철수")
student1 = Student("이영희", "2025001")
people = [person1, student1]
print("\n다형성을 이용한 인사하기:")
for person_obj in people:
# 같은 person_obj.greet() 호출이지만,
# 객체의 실제 타입(Person, Student)에 따라 다른 메시지가 출력됩니다.
print(person_obj.greet())
코드 설명 (동물 예제 기준):
- class Animal::
- __init__(self, name): 동물의 이름을 초기화합니다.
- speak(self): 동물이 소리를 내는 메서드입니다. NotImplementedError를 발생시켜, 이 클래스를 상속받는 자식 클래스에서 반드시 이 메서드를 **오버라이드(재정의)**해야 함을 명시합니다. (필수는 아니지만 좋은 관행입니다.)
- class Dog(Animal):, class Cat(Animal):, class Cow(Animal)::
- 각각 Animal 클래스를 상속받습니다.
- speak(self) 메서드를 각 동물에 맞게 오버라이드하여 고유한 소리를 내도록 구현합니다. 예를 들어, Dog는 "멍멍!", Cat은 "야옹~"을 반환합니다.
- 객체 생성 및 리스트 활용:
- Dog, Cat, Cow 타입의 객체들을 생성합니다.
- 이 객체들을 animals라는 하나의 리스트에 담습니다. 중요한 점은 이 리스트에는 Animal의 자식 클래스 객체들이 섞여 있다는 것입니다.
- 다형성 실행:
- for animal in animals: 루프를 통해 리스트의 각 객체에 대해 animal.speak()를 호출합니다.
- 여기서 다형성이 발현됩니다. animal.speak()라는 동일한 형태의 코드를 호출하지만, animal 변수가 실제로 어떤 객체(Dog인지, Cat인지, Cow인지)를 가리키느냐에 따라 실행되는 speak 메서드의 내용이 달라집니다.
- animal이 Dog 객체일 때는 Dog 클래스의 speak 메서드가 호출됩니다.
- animal이 Cat 객체일 때는 Cat 클래스의 speak 메서드가 호출됩니다.
- animal이 Cow 객체일 때는 Cow 클래스의 speak 메서드가 호출됩니다.
다형성(Polymorphism)의 핵심:
"여러 형태를 가질 수 있다"는 의미로, 동일한 이름의 메서드가 서로 다른 클래스에서 다른 방식으로 동작하는 것을 말합니다. 이를 통해 코드의 유연성과 확장성을 높일 수 있습니다. 위 예제에서는 speak()라는 동일한 요청에 대해 각 동물 객체가 자신만의 방식으로 응답하는 것을 볼 수 있습니다.
Person/Student 예제에서의 다형성:
Person 클래스와 이를 상속한 Student 클래스 모두 greet() 메서드를 가지고 있습니다. Student 클래스는 greet() 메서드를 자신에게 맞게 재정의(오버라이드)했습니다. people 리스트에 Person 객체와 Student 객체를 함께 넣고, 각 객체의 greet() 메서드를 호출하면 객체의 실제 타입에 따라 다른 인사말이 출력됩니다. 이것 또한 다형성의 예입니다.
'Python' 카테고리의 다른 글
| 파이썬 예외 처리 (0) | 2025.05.14 |
|---|---|
| 파이썬 다형성이 뭐였지? (2) | 2025.05.14 |
| 파이썬 상속 예제 (0) | 2025.05.14 |
| 함수 정의 및 호출 (0) | 2025.05.12 |
| 파이썬 클래스와 객체란? (0) | 2025.05.12 |