본문 바로가기
파이썬

파이썬 상속, 다형성 이해하기

by python pro 2023. 1. 26.
반응형

 

상속

Python에서 상속(Inheritance)란 기존의 클래스(부모 클래스)를 상속받아 새로운 클래스(자식 클래스)를 정의하는 것을 말합니다. 상속을 통해 기존의 클래스에 정의된 메서드와 변수를 새로운 클래스에서도 사용할 수 있게 됩니다.

 

다음은 Person 클래스를 상속받는 Student 클래스를 정의하는 예시입니다.

class Person:
    def __init__(self, name):
        self.name = name
    
    def say_hello(self):
        print("Hello, my name is {}".format(self.name))

class Student(Person):
    def __init__(self, name, student_id):
        super().__init__(name)
        self.student_id = student_id
    
    def say_hello(self):
        super().say_hello()
        print("I am a student, my student ID is {}".format(self.student_id))

Student 클래스는 Person 클래스를 상속받아 정의하였습니다. Person 클래스에서 정의된 name 변수와 say_hello 메서드를 Student 클래스에서도 사용할 수 있습니다. 또한 Student 클래스는 student_id 변수와 say_hello 메서드를 추가로 정의하였습니다.

 

Student 클래스의 __init__ 메서드에서는 super().__init__(name)를 호출하여 Person 클래스의 생성자를 호출하고, student_id를 초기화 합니다. say_hello 메서드에서는 super().say_hello()를 호출하여 Person 클래스의 say_hello 메서드를 호출하고, 추가로 "I am a student, my student ID is {}".format(self.student_id)를 출력합니다.

 

이제 Person 클래스와 Student 클래스를 인스턴스화 하여 메서드를 호출해보겠습니다.

p = Person("John Smith")
p.say_hello()
# Output: Hello, my name is John Smith

s = Student("Jane Doe", "12345")
s.say_hello()
# Output: Hello, my name is Jane Doe
#         I am a student, my student ID is 12345

위 코드는 정상적인 코드 예시입니다.

하지만 아래코드는 잘못된 코드 예시입니다.

class Student(Person):
    def __init__(self, student_id):
        self.student_id = student_id

s = Student("12345")
s.say_hello()
# AttributeError: 'Student' object has no attribute 'name'

위 코드는 Student 클래스의 생성자에서 super().__init__(name)를 호출하지 않아, Person 클래스의 name 변수를 초기화 하지 않아 생기는 문제입니다. 그렇기 때문에 s.say_hello()를 호출할 때 Attribute error가 발생합니다.

 

만약 Student 클래스에서 name 변수를 초기화 하려면 생성자에서 super().__init__(name)를 호출하거나 Person.__init__(self, name)를 호출하는 것도 가능합니다.

 

이와 같은 상속을 통해 기존의 클래스를 기반으로 새로운 클래스를 정의하면 코드의 재사용성을 높일 수 있습니다.

 

다형성

Python에서는 다형성(Polymorphism)이라는 개념도 지원합니다. 다형성은 같은 인터페이스를 가진 다른 클래스를 동일한 방식으로 사용할 수 있다는 것을 말합니다.

 

예를 들어, 아래 코드에서 Animal 클래스를 상속받는 Dog, Cat 클래스를 정의하였고 각각의 클래스는 speak() 메서드를 오버라이딩 하였습니다.

class Animals:
    def speak(self):
        pass

class Dog(Animals):
    def speak(self):
        return "Woof"

class Cat(Animals):
    def speak(self):
        return "Meow"

이제 각각의 클래스를 인스턴스화 하여 speak() 메서드를 호출해보겠습니다.

dog = Dog()
cat = Cat()

print(dog.speak()) # Output: Woof
print(cat.speak()) # Output: Meow

위 코드는 정상적인 코드 예시입니다.

다형성을 사용하면 같은 인터페이스를 가진 객체를 동일한 방식으로 사용할 수 있어 코드의 재사용성을 높일 수 있습니다.

 

상속과 다형성은 객체지향 프로그래밍에서 중요한 개념입니다. 이를 이해하고 적용하면 더욱 깔끔하고 유지보수가 용이한 코드를 작성할 수 있습니다. 하지만 상속과 다형성을 잘못 사용할 경우 코드의 구조를 복잡하게 만들고 유지보수를 어렵게 만들 수 있으니 주의해야합니다.

 

 

아래에는 실제 업무에 적용될 수 있는 예시 코드를 공유해드립니다.

# 상속을 이용한 예제
class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    def display_info(self):
        print("Name: {}".format(self.name))
        print("Salary: {}".format(self.salary))
        
class Manager(Employee):
    def __init__(self, name, salary, department):
        super().__init__(name, salary)
        self.department = department
    
    def display_info(self):
        super().display_info()
        print("Department: {}".format(self.department))
        
e = Employee("John Smith", 50000)
e.display_info()
# Output: Name: John Smith
#         Salary: 50000

m = Manager("Jane Doe", 60000, "IT")
m.display_info()
# Output: Name: Jane Doe
#         Salary: 60000
#

 

 

위 예제는 상속을 이용하여 Employee 클래스를 기반으로 Manager 클래스를 정의하며, Manager 클래스는 Employee 클래스의 display_info 메서드를 상속받아 department를 추가로 출력하는 기능을 구현하였습니다.

 

# 다형성을 이용한 예제
class Shape:
    def area(self):
        pass
    
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
        
    def area(self):
        return self.width * self.height
    
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
        
    def area(self):
        return 3.14 * self.radius ** 2
    
def display_area(shape):
    print("Area is:", shape.area())
    
rect = Rectangle(10, 20)
display_area(rect) # Output: Area is: 200

circ = Circle(5)
display_area(circ) # Output: Area is: 78.5

두번째 예제는 다형성을 이용하여 Shape 클래스를 기반으로 Rectangle 클래스와 Circle 클래스를 정의하며, 각각의 클래스는 area() 메서드를 오버라이딩 하여 자신의 면적을 구하는 기능을 구현하였습니다. 그리고 display_area 함수를 정의하여 Shape 클래스를 상속받은 Rectangle 클래스와 Circle 클래스의 인스턴스를 파라미터로 받아 각각의 면적을 출력하는 기능을 구현하였습니다. 이렇게 함으로써 같은 인터페이스를 가진 다른 클래스를 동일한 방식으로 사용할 수 있게 되었습니다.

반응형

'파이썬' 카테고리의 다른 글

파이썬 클래스메소드  (0) 2023.01.26
파이썬 캡슐화, 은닉화 이해하기  (0) 2023.01.26
파이썬 클래스 정의하기  (0) 2023.01.26
파이썬 dictionary comprehension  (0) 2023.01.25
파이썬 list comprehension  (0) 2023.01.25

댓글