[파이썬] 클래스 상속연결하기(Method Overriding)
- Python/기초
- 2023. 12. 11.
클래스 연결
메서드 오버라이딩(Method Overriding)은 객체 지향 프로그래밍에서 하위 클래스가 상위 클래스로부터 상속받은 메서드를 재정의하는 개념입니다. 이는 상속 관계에 있는 클래스 간에 동일한 메서드 이름을 사용하면서 각 클래스에서 특정 메서드의 동작을 변경하고자 할 때 사용됩니다.
메서드 오버라이딩의 주요 특징은 다음과 같습니다:
- 상속 관계 필요: 메서드 오버라이딩은 부모 클래스와 자식 클래스 간의 상속 관계에서만 발생합니다.
- 메서드 시그니처 동일: 오버라이딩되는 메서드는 메서드 시그니처(이름, 매개변수 형식, 반환 형식)가 부모 클래스의 메서드와 동일해야 합니다.
- 동적 바인딩: 어떤 메서드가 호출될지는 객체의 실제 타입에 따라 동적으로 결정됩니다. 즉, 실행 시간에 객체의 실제 타입을 고려하여 오버라이딩된 메서드가 호출됩니다.
간단한 예제를 통해 메서드 오버라이딩을 살펴보겠습니다.
class Animal:
def make_sound(self):
print("Generic animal sound")
class Dog(Animal):
def make_sound(self):
print("Bark, bark!")
class Cat(Animal):
def make_sound(self):
print("Meow, meow!")
# 메서드 오버라이딩 사용
dog = Dog()
dog.make_sound() # "Bark, bark!"
cat = Cat()
cat.make_sound() # "Meow, meow!"
이 예제에서 Dog
와 Cat
클래스는 Animal
클래스를 상속받습니다. 각각의 하위 클래스에서 make_sound
메서드를 오버라이딩하여 동물의 소리를 특화시켰습니다. 이렇게 하면 같은 메서드 이름을 사용하면서도 다양한 하위 클래스에서 메서드의 동작을 다르게 정의할 수 있습니다.
사실 상속 없이도 가능
위의 예제는 확실히 상속이 일어났습니다. 그렇기 때문에 Animal()이 정의 되어있는 상태에서만 일어납니다. 그렇지만 저런 상속은 필요없습니다. 안해도 똑같이 됩니다.
class Dog():
def speak(self):
print("강아지가 짖습니다.")
dog = Dog()
dog.speak()
명령을 하는데 아무 하자가 없습니다. 그렇다면 도대체 상속은 언제 해야할까요?
상속이 필요한 경우
상속이 필요한 경우는 크게 4가지로 나눠집니다.
1. 계층 구조 필요
상속을 이용하면 계층 구조를 만들 수 있습니다. 계층구조가 되면 코드 이해와 유지보수가 쉬워집니다. 위의 예제에서 상속이 된 경우는 누군가가 보면 상속관계를 그려낼 수 있기에 클래스간 어떤 것들이 주고받는지알 수 있게 됩니다.
2. 다형성이 필요한 경우
클래스 상속은 다형성을 지원합니다. 부모 클래스 타입으로 선언된 변수는 자식 클래스의 객체를 가리킬 수 있습니다. 이는 유연성을 제공하며, 동일한 메소드 호출을 통해 서로 다른 하위 클래스의 특정 동작을 활용할 수 있습니다.
3. 추상화와 공통된 인터페이스 필요
부모 클래스에서는 추상적으로 메소드를 만들고 자식 클래스에서 이를 구현함으로써 추상화와 일관된 인터페이스를 유지할 수 있습니다. 이는 코드의 일관성을 높이고 개발자에게 특정 메소드의 구현을 강제함으로써 코드의 예측 가능성을 높입니다.
4. 코드 재사용과 중복 제거
클래스 상속을 통해 부모 클래스의 속성과 메소드를 자식 클래스에서 재사용할 수 있습니다. 이는 중복 코드를 방지하고 코드의 재사용성을 높일 수 있습니다.
예제
서로 데이터를 주고받는 상속을 구현해보겠습니다.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name}이(가) 소리를 냅니다.")
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
def bark(self):
print(f"{self.name}이(가) {self.breed} 품종의 강아지가 짖습니다.")
class Cat(Animal):
def __init__(self, name, color):
super().__init__(name)
self.color = color
def meow(self):
print(f"{self.color} 고양이 {self.name}이(가) 야옹합니다.")
# 객체 생성
animal = Animal("동물")
dog = Dog("멍멍이", "시바견")
cat = Cat("야옹이", "흰색")
# 메소드 호출
animal.speak() # "동물이 소리를 냅니다."
dog.speak() # "멍멍이이(가) 소리를 냅니다."
dog.bark() # "멍멍이이(가) 시바견 품종의 강아지가 짖습니다."
cat.speak() # "야옹이이(가) 소리를 냅니다."
cat.meow() # "흰색 고양이 야옹이이(가) 야옹합니다."
Dog에는 speak()메쏘드가 없지만 dog.speak()를 명령하면 Animal 클래스에 있는 speak()를 가져다 씁니다.
Animal 클래스는 자식 클래스인 Dog의 Name 을 가져와서 speak()를 이행하게 됩니다.
Animal 클래스의 speak() 메쏘드에 어느것이든 들어맞을 수 있게 조정을 해주어 자식 클래스에 있는 어떤 값이 입력되든 쓸 수 있게 해주면 좀 더 편리하게 코딩작업을 할 수 있습니다.
마치며
메소드 오버라이딩에 대해서 알아보았습니다. 현재 예제는 간단하게 보였지만 실제 개발에서는 복잡한 코드를 하게 되니 상속을 쓰는 게 더 편해질지도 모릅니다. 부모 자식 클래스간의 소통이 어떻게 이뤄지는게 효율적인지 고민하셔서 유용하게 활용하시기 바랍니다.
'Python > 기초' 카테고리의 다른 글
파이썬에서의 ~ 연산자 : 비트 반전과 논리 NOT 연산 (0) | 2024.05.30 |
---|---|
[파이썬] 리스트 같은 원소값 가져오기 (0) | 2024.05.25 |
[파이썬] 딕셔너리 합치기(key 같을 때 정리) (0) | 2023.11.23 |
[파이썬] 인스턴스 타입 확인하고 넘기기(객체 동적 확인) (0) | 2023.11.18 |
[파이썬] 리스트 복사하기 (0) | 2023.10.16 |