흔히 저희가 알고 있는 상속은 부모로부터 자식이 받는 재산, 현금 등을 말하는 것을 알고 있습니다. 그런데 파이썬에서 상속??이라고 생각할 수 있지만
파이썬에서도 비슷한 개념이 있습니다. 지금부터 확인해보겠습니다.
파이썬에서 상속은 한 클래스의 속성과 메서드를 다른 클래스에 전달하는 기능을 의미합니다. 상속을 사용하면 기존의 코드를 재사용하고 확장할 수 있습니다. 기본적으로 파이썬의 모든 클래스는 object라는 기본 클래스로부터 상속받습니다.
속은 어떻게 사용되는지 알아보겠습니다.
Parent는 기본 클래스이며 부모 클래스라고도 불립니다. Parent 클래스에 상속받은 Child는 파생 클래스이며 자식 클래스라고도 불립니다.
이번엔 상속한 경우에 생성자 호출 순서에 대해서 알아보겠습니다.
child 인스턴스를 통해 Child 클래스를 호출하게 되면 순서는 다음과 같습니다.
1. Child의 생성자를 호출합니다.
2. super() 함수에 의해 부모 클래스로 올라가 부모 클래스의 생성자를 호출합니다.
3. 부모 클래스의 생성자의 실행이 끝나면 Child클래스의 생성자로 돌아와 실행됩니다.
object는 파이썬의 모든 클래스의 기본 클래스입니다. object 클래스는 파이썬에서 모든 객체의 기본적인 동작과 특성을 정의합니다.
부모 클래스에게 상속을 받은 자식 클래스가 메소드를 새롭게 설정할 수 있습니다. 이를 메소드 오버라이딩이라고 합니다.
메서드 오버라이딩(Method Overriding)은 객체 지향 프로그래밍에서 중요한 개념 중 하나로, 서브 클래스(자식 클래스)에서 슈퍼 클래스(부모 클래스)의 메서드를 재정의하는 것을 의미합니다. 오버라이딩을 사용하면, 서브 클래스에서 상속받은 메서드의 동작을 변경하거나 확장할 수 있습니다.
위의 예시에서는 Dog클래스에서 run메소드를 확장했음을 알 수 있습니다.
Animal 클래스에서 정의했던 eat 메소드를 Dog 클래스에서 다시 재정의한 것을 확인할 수 있습니다. 또 superEat 메소드를 통해 Dog 클래스에서 Animal 클래스로 올라가 eat메소들 사용할 수 있게 메소드를 설정했습니다. super()함수에 대해서는 밑에서 더 살펴보도록 하겠습니다.
따라서 Rucy.eat()를 통해 자식 클래스의 eat 메소드를 호출하는 것을 볼 수 있고 Rucy.superEat()를 통해 부모 클래스에서의 eat메소드를 호출함을 확인할 수 있습니다.
자식 클래스는 부모 클래스에게 상속 받기 때문에 부모 클래스의 메소드를 사용할 수 있는 반면 부모 클래스는 자식 클래스의 메소드를 사용할 수 없습니다.
지금까지는 한 개의 부모 클래스로부터 상속받은 경우에 대해서 확인했습니다. 두 개 이상의 부모 클래스로부터 상속을 받는 다중 상속에 대해서 살펴보겠습니다.
다중 상속은 클래스가 둘 이상의 부모 클래스로부터 상속을 받는 기능을 의미합니다. 파이썬은 다른 많은 객체 지향 언어와 달리 다중 상속을 지원합니다. 다중 상속을 사용하면 코드의 재사용성을 향상시킬 수 있지만, 동시에 복잡성이 높아지기 때문에 주의해야 합니다.
Child 클래스는 Parent1과 Parent2에게 상속받은 자식 클래스입니다.
MRO를 통해 다중 상속에서 메서드 해결 순서를 알 수 있습니다.
super()는 파이썬의 내장 함수로서, 상속과 관련된 작업을 수행할 때 사용됩니다. 특히, 자식 클래스에서 부모 클래스의 메서드를 호출할 때 사용됩니다. super()의 주요 목적은 자식 클래스에서 부모 클래스의 메서드를 오버라이드(재정의)하면서도 그 오버라이드된 메서드 내에서 부모 클래스의 원본 메서드를 호출하는 것입니다.
child.hello()를 통해 Child클래스의 hello 메소드로 올라갑니다.
super().hello()를 통해 부모 클래스인 Parent클래스로 올라가야 함을 알 수 있습니다.
Parent 클래스의 hello 메소드를 실행하면 '부모 클래스의 hello 메서드'가 출력되고 다시 Child클래스의 hello()메소드로 돌아와 '자식 클래스이 hello 메서드'를 출력하게 됩니다.
더 나아가 __init_() 메소드를 사용하여 자식 클래스에서 부모 클래스의 생성자를 호출하여 부모 클래스의 속성을 이용할 수 있게 해줍니다.
여러 개의 부모 클래스에게 상속 받은 자식 클래스를 이용하여 사용할 때에 MRO를 이용하여 명확하게 출력되는 방향을 파악할 수 있습니다.
child 인스턴스를 이용하여 child.hello()를 실행시켜 보면 순서는 다음과 같습니다.
Child클래스로 와 hello()메소드를 실행하려고 합니다. 'Child의 Hello'를 우선 출력합니다.
super().hello()가 있는 것으로 보아 부모 클래스로 올라가야 합니다. 그런데 상속 관계가 복잡하게 얽혀 있기 때문에 Child.mro()를 확인하여 순서를 명확하게 파악합니다.
Child 다음 순서인 A클래스의 hello 메소드를 호출합니다. 'A의 hello'가 출력된 후 다시 super().hello() 접하게 됩니다.
mro의 순서에 의해 B클래스의 hello 메소드를 호출합니다. 'B의 hello'가 출력된 후 다시 super().hello() 접하게 됩니다.
mro의 순서에 의해 Base클래스의 hello 메소드를 호출합니다. 'Base의 hello', 'Base 클래스이 hello 메서드'가 순서대로 출력됩니다.
다시 mro의 순서에 의해 이번에는 반대 방향을 따라갑니다.
B클래스의 hello() 메소드를 호출하여 'B 클래스의 hello 메서드 호출'을 출력합니다.
다음 순서인 A클래스의 hello() 메소드를 호출하여 ' A 클래스의 hello 메서드'를 출력합니다.
마지막으로 Child 클래스로 돌아와 hello() 메소드를 호출하여 'Child 클래스의 hello 메서드 호출'이 출력되어 실행이 종료됩니다.
Python 18. 예외 처리 (0) | 2024.03.21 |
---|---|
Python 17. Special method (0) | 2024.03.20 |
Python 15. 객체 지향과 클래스 (0) | 2024.03.20 |
Python 14. 콜백함수와 람다함수 (0) | 2024.03.19 |
Python 13. 변수의 범위! (2) | 2024.03.19 |