[파이썬] 리스코프 치환 원칙과 하위 클래스

리스코프 치환 원칙(Liskov Substitution Principle, LSP)은 객체 지향 프로그래밍의 중요한 원칙 중 하나입니다. 이 원칙은 상속 관계에서 하위 클래스가 상위 클래스의 인스턴스처럼 동작할 수 있어야 한다는 개념을 설명합니다. 즉, 부모 클래스의 인스턴스를 대체하여 사용해도 기존 코드의 정확성을 유지해야 한다는 것입니다.

이 원칙은 코드의 재사용성, 유지 보수성, 확장성을 높이는 데 도움을 줍니다. 하지만 제대로 구현하지 않았을 경우 예기치 않은 버그가 발생할 수 있습니다.

LSP의 핵심 원칙

LSP는 다음과 같이 요약될 수 있습니다:

  1. 하위 클래스는 최소한 기존의 동작을 유지해야 한다.
  2. 하위 클래스는 기존의 동작을 확장할 수 있다.
  3. 하위 클래스는 절대 기존의 동작을 변경하거나 무효화해서는 안 된다.

예제를 통한 설명

아래는 Python에서 LSP를 지켜야 하는 예제 코드입니다.

class Animal:
    def make_sound(self):
        pass


class Dog(Animal):
    def make_sound(self):
        return "Woof"


class Cat(Animal):
    def make_sound(self):
        return "Meow"

위의 코드에서 Animal 클래스는 추상적인 동물을 나타내는 기본 클래스입니다. make_sound()라는 추상 메서드를 가지고 있으며 하위 클래스에서 반드시 구현되어야 합니다.

DogCatAnimal 클래스를 상속받아 구현된 구체적인 동물 클래스입니다. 각각 make_sound() 메서드를 오버라이딩하여 개와 고양이의 소리를 출력하도록 구현했습니다.

def animal_sound(animal):
    print(animal.make_sound())

animal_sound() 함수는 Animal 클래스의 인스턴스를 파라미터로 받아서 make_sound() 메서드를 호출합니다.

dog = Dog()
cat = Cat()

animal_sound(dog)  # 출력: Woof
animal_sound(cat)  # 출력: Meow

dogcatAnimal 클래스의 인스턴스이므로 animal_sound() 함수에서 정상적으로 호출할 수 있습니다. 이는 LSP를 준수한 결과입니다.

결론

리스코프 치환 원칙은 객체 지향 프로그래밍에서 중요한 원칙 중 하나입니다. 하위 클래스가 상위 클래스로 대체될 수 있는지 여부는 코드의 안전성과 유연성을 결정짓는 중요한 요소입니다. LSP를 지키면 코드의 재사용성이 증가하고 유지 보수 비용을 줄일 수 있습니다. 따라서 LSP를 적용해서 안정적이고 확장 가능한 코드를 작성하는 것이 좋습니다.