제로베이스 데이터 파트타임 스쿨 학습 일지 [25.04.02]

[강의 요약]

[Ch 03. 파이썬 중급] 강의 수강

25_다중 상속부터 27_추상클래스까지 강의 수강하였음

🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰░                                             ] 17/100일 (17%)

바쁘지만 쉴 수가 없다!

 

 

[다중 상속]

  • 다중 상속이란?
    • 하나의 클래스가 두 개 이상의 클래스를 상속받는 것
    • Multiple Inheritance

 

하나의 클래스가 여러 부모 클래스로부터 속성과 메서드를 물려받을 수 있음

Car01, Car02, Car03 클래스가 각각 drive(), turbo(), fly() 기능을 가지고 있다면

이 모든 기능을 Car 클래스 하나에 통합해서 사용할 수 있음

class Car(Car01, Car02, Car03):
    def __init__(self):
        pass
myCar = Car()
myCar.drive()   # Car01에서 상속
myCar.turbo()   # Car02에서 상속
myCar.fly()     # Car03에서 상속

 

 

▶ 다중 상속(자동차 기능 통합) 코드

class Car01:
    def drive(self):
        print('drive() method called!!')

class Car02:
    def turbo(self):
        print('turbo() method called!!')

class Car03:
    def fly(self):
        print('fly() method called!!')

class Car(Car01, Car02, Car03):
    def __init__(self):
        pass

myCar = Car()
myCar.drive()
myCar.turbo()
myCar.fly()

각각의 기능을 독립된 클래스로 나눠서 정의한 뒤

Car 클래스에서 이들을 상속받아 객체 하나로 기능을 통합했음

 

 

 

▶ 실습 코드 : 계산기 기능 확장

class Calculator(BasicCalculator, DeveloperCalculator):
    def __init__(self):
        pass

myCal = Calculator()
print(myCal.add(10, 20))    # 30
print(myCal.sub(10, 20))    # -10
print(myCal.mul(10, 20))    # 200
print(myCal.div(10, 20))    # 0.5

print(myCal.mod(10, 3))     # 1
print(myCal.flo(10, 3))     # 3
print(myCal.exp(10, 3))     # 1000

기본적인 사칙연산 기능은 BasicCalculator에

개발자용 연산기능은 DeveloperCalculator에 분리

이 둘을 상속받은 Calculator 클래스에서 모든 기능을 한 번에 사용할 수 있도록 만들었음

 

 

▶ 요약

  • 다중 상속은 여러 클래스를 한 번에 상속받아 기능을 하나의 클래스에 모을 수 있음
  • 코드의 재사용성과 유지 보수성이 향상되기에 사용함
  • But. 너무 많은 클래스를 상속받으면 복잡도가 증가
    • 상속 구조는 단순하고 명확하게 설계하는 것이 중요

 

 

 

 

[오버라이딩]

  • 오버라이딩이란?
    • 하위 클래스(자식 클래스)에서 상위 클래스(부모 클래스)의 메서드를 재정의(Override)하는 것
    • 같은 이름의 메서드를 다시 정의해서 동작을 바꾸는 것이 핵심

 

 

▶ 예제 코드 : 총알을 레이저로

class Robot:
    def fire(self):
        print('총알 발사!!')

class NewRobot(Robot):
    def fire(self):
        super().fire()
        print('레이저 발사!!')

 

Robot 클래스에는 기본 공격인 "총알 발사!!"가 있고

NewRobot은 Robot을 상속받지만

fire() 메서드를 다시 정의해서

"총알 발사!!"와 함께 "레이저 발사!!"도 출력되게 함

 

myRobot = NewRobot()
myRobot.fire()

# 출력결과
'''
총알 발사!!
레이저 발사!!
'''

 

 

▶ 실습 코드 : 삼각형 넓이 표현 설정

class TriangleArea:
    def getArea(self):
        return self.width * self.height / 2

class NewTriangleArea(TriangleArea):
    def getArea(self):
        return str(super().getArea()) + '㎠'

 

TriangleArea 클래스는 숫자값만 반환하지만

NewTriangleArea는 getArea()를 오버라이딩해서

단위까지 포함된 문자열로 결과를 리턴함

ta = NewTriangleArea(7, 5)
print(ta.getArea())  # 출력: 17.5㎠

 

 

 

▶ 요약

  • 오버라이딩은 클래스 상속 시 자식 클래스에서 기능을 덮어쓰기 위해 사용
  • super()를 통해 부모 클래스의 원래 기능도 함께 사용할 수 있음
  • 동일한 이름의 메서드라도 자식 클래스에서는 다르게 동작하도록 만들 수 있음

 

 

 

 

[추상 클래스]

  • 추상 클래스란?
    • '설계도'같은 역할을 하는 클래스
    • 실제로 사용할 수는 없고, 상속받은 자식 클래스가 꼭 어떤 메서드를 구현해야 한다는 규직을 강제할 수 있음
    • 사용하는 이유는 코드의 일관성과 유지보수성이 좋아지기 때문

 

 

▶ 선언 방법

from abc import ABCMeta, abstractmethod

class MyClass(metaclass=ABCMeta):
    @abstractmethod
    def myMethod(self):
        pass

 

ABCMeta는 추상 클래스를 만들기 위한 메타 클래스

@abstractmethod 데코레이터를 붙이면, 자식 클래스가 반드시 해당 메서드를 구현해야 함!

 

 

 

▶ 예제 코드 : 비행기

class AirPlane(metaclass=ABCMeta):
    @abstractmethod
    def flight(self):
        pass

 

AirPlane은 추상 클래스. flight() 메서드만 선언해 놓고 실제 구현은 안 되어 있음

자식 클래스는 이 flight()를 무조건 오버라이딩(재정의) 해야 함

 

class Airliner(AirPlane):
    def flight(self):
        print('시속 400km/h 비행!!')
class fighterPlane(AirPlane):
    def flight(self):
        print('시속 700km/h 비행!!')

 

Airliner, fighterPlane 클래스는 각각 flight() 기능을 자기 방식대로 구현함

이처럼 공통된 틀은 추상 클래스가 제공, 세부 기능은 자식이 알아서 만든다는 것

 

 

 

▶ 실습 코드 : 계산기 클래스

class Calculator(metaclass=ABCMeta):
    @abstractmethod
    def add(self, n1, n2): pass
    @abstractmethod
    def sub(self, n1, n2): pass
    @abstractmethod
    def mul(self, n1, n2): pass
    @abstractmethod
    def div(self, n1, n2): pass

Calculator 클래스는 덧셈, 뺄셈, 곱셈, 나눗셈을 반드시 구현해야 한다는 규칙만 정의한 클래스

class ChildCalculator(Calculator):
    def add(self, n1, n2): print(n1 + n2)
    def sub(self, n1, n2): print(n1 - n2)
    def mul(self, n1, n2): print(n1 * n2)
    def div(self, n1, n2): print(n1 / n2)

실제 기능은 ChildCalculator가 모두 구현했기 때문에 객체 생성이 가능

 

 

▶ 요약

  • @abstractmethod
    • 자식 클래스에서 반드시 구현해야 하는 메서드 지정
  • ABCMeta
    • 추상 클래스의 기반이 되는 메타 클래스
  • 사용 목적
    • 공통 구조를 강제하고, 일관된 코딩 스타일 유지

 

 

 

 

[나의 생각 정리]

  • 상속으로 기능을 재사용할 수 있다.
  • 다중 상속은 여러 클래스를 한 번에 쓸 수 있어 유용하다.
  • 오버라이딩은 같은 이름의 기능을 다르게 구현한다.
  • 추상 클래스는 꼭 구현해야 할 기능을 정해줄 수 있다.

 

[적용점]

  • 비슷한 클래스는?
    • 상속으로 간결하게 만들자
  • 필요한 기능만 골라 쓰고 싶을 때?
    • 다중 상속
  • 부모 기능을 살리면서 확장하고 싶을 때?
    • super()
  • 자식 클래스에 따라 다르게 동작하게 하려면?
    • 오버라이딩
  • 클래스 구조가 복잡할 땐?
    • 추상 클래스로 먼저 틀 잡기

 

 

 

“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”