본문 바로가기

설계

[파이썬] 상속성 (Inheritance)

상속성(Inheritance)은 객체지향 프로그래밍에서 중요한 개념 중 하나로, 이미 존재하는 클래스를 기반으로 새로운 클래스를 정의하는 것을 의미합니다. 상속을 사용하면, 이미 존재하는 클래스의 모든 속성과 메소드를 새로운 클래스에서 사용할 수 있습니다.

예를 들어, 자동차 클래스와 스포츠카 클래스를 생각해보겠습니다. 자동차 클래스는 자동차의 기본적인 속성과 메소드를 갖고 있고, 스포츠카 클래스는 자동차 클래스를 상속받아서 자신만의 추가적인 속성과 메소드를 갖게 됩니다.

 

1. 예제 코드


이제 Python 코드로 간단한 예제를 살펴보겠습니다.

 

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

    def start_engine(self):
        print("Engine started")

class SportsCar(Car):
    def __init__(self, make, model, year, max_speed):
        super().__init__(make, model, year)
        self.max_speed = max_speed

    def drive_fast(self):
        print(f"Driving at {self.max_speed} mph")

my_sports_car = SportsCar("Porsche", "911", 2021, 200)
print(my_sports_car.make)  # Output: Porsche
print(my_sports_car.year)  # Output: 2021
my_sports_car.start_engine()  # Output: Engine started
my_sports_car.drive_fast()  # Output: Driving at 200 mph


위 예제에서, SportsCar 클래스는 Car 클래스를 상속받습니다. SportsCar 클래스는 __init__ 메소드를 정의하여, 자신의 속성인 max_speed를 초기화하고, super() 함수를 사용하여 Car 클래스의 __init__ 메소드를 호출하여 부모 클래스의 속성들을 초기화합니다. SportsCar 클래스는 drive_fast 메소드를 정의하여, 스포츠카의 특성인 빠른 주행을 나타냅니다.

이제 my_sports_car 객체를 생성하고, make, year, start_engine, drive_fast 속성과 메소드에 접근하여 출력 결과를 확인할 수 있습니다. 이것이 상속성이 제공하는 기본적인 기능입니다.


2. 다중상속


다중상속(Multiple Inheritance)은 객체지향 프로그래밍에서 한 클래스가 둘 이상의 클래스를 상속받는 것을 의미합니다. 파이썬은 다중상속을 지원하는 언어 중 하나입니다.

다중상속은 코드 재사용과 유연성을 높여주는 장점이 있지만, 상속 그 자체가 복잡한 개념이므로 다중상속은 코드를 이해하기 어렵게 만들 수 있습니다. 또한, 다중상속을 사용하면 상속 관계가 복잡해지고 메소드 이름 충돌 등의 문제가 발생할 수 있습니다.

따라서, 다중상속을 사용하기 전에 잘 고려해야 합니다. 만약 다중상속을 사용해야 한다면, 다음과 같은 지침을 따르는 것이 좋습니다.

다중상속을 사용할 때는 상속할 클래스들의 관계를 잘 파악하고, 각 클래스들의 역할과 책임을 명확히 정의해야 합니다.

다이아몬드 문제와 같은 메소드 이름 충돌 문제를 방지하기 위해서는 메소드 이름 충돌을 막기 위한 방법을 사용해야 합니다. 파이썬에서는 Method Resolution Order(MRO) 알고리즘을 사용하여 다중상속으로부터 발생할 수 있는 메소드 이름 충돌 문제를 해결합니다.

다중상속을 사용할 때는 클래스의 상속 순서를 잘 고려해야 합니다. MRO 알고리즘이 적용되기 때문에, 상속 순서에 따라 결과가 달라질 수 있습니다.

예를 들어, 다음과 같은 코드에서는 Vehicle과 Electric 클래스를 상속받는 ElectricVehicle 클래스를 정의하고 있습니다.

 

class Vehicle:
    def __init__(self, make, model):
        self.make = make
        self.model = model

class Electric:
    def __init__(self, battery_size):
        self.battery_size = battery_size

class ElectricVehicle(Vehicle, Electric):
    def __init__(self, make, model, battery_size):
        Vehicle.__init__(self, make, model)
        Electric.__init__(self, battery_size)



이 예제에서 ElectricVehicle 클래스는 Vehicle 클래스와 Electric 클래스를 다중상속받고 있습니다. 이를 통해 ElectricVehicle 클래스는 전기차의 속성을 가지면서도 Vehicle 클래스의 모든 속성을 상속받을 수 있습니다.

하지만, 만약 ElectricVehicle 클래스에서 Vehicle 클래스와 Electric 클래스 모두에서 같은 이름의 속성이나 메소드를 가지고 있다면, MRO 알고리즘에 의해 상속 순서에 따라 우선순위가 결정됩니다. 만약 ElectricVehicle 클래스에서 __init__ 메소드를 호출한다면, MRO 알고리즘에 따라 먼저 Vehicle 클래스의 __init__ 메소드가 호출되고, 그 다음에 Electric 클래스의 __init__ 메소드가 호출됩니다.

예를 들어, 다음과 같이 ElectricVehicle 객체를 생성하면서 make, model, battery_size 인자를 전달해보겠습니다.

 

my_car = ElectricVehicle('Tesla', 'Model S', '100kWh')
print(my_car.make)
print(my_car.model)
print(my_car.battery_size)



이 코드를 실행하면 다음과 같은 결과가 출력됩니다.

 

Tesla
Model S
100kWh


이를 통해, ElectricVehicle 클래스가 Vehicle 클래스와 Electric 클래스의 속성을 모두 상속받고 있음을 확인할 수 있습니다.

하지만, 만약 Vehicle 클래스와 Electric 클래스에서 같은 이름의 메소드가 있다면, MRO 알고리즘에 따라 어떤 메소드가 호출될지 예측하기 어려울 수 있습니다. 따라서, 다중상속을 사용할 때는 메소드 이름 충돌을 방지하기 위해 조심해야 합니다.