본문 바로가기
Programming/python

파이썬 메서드 오버라이딩(Overriding) vs 오버로딩(Overloading)

by 조창대 2022. 10. 14.
반응형

클래스를 공부하며 캡슐화, 상속, 재정의, 다형성 등의 객체 지향 개념을 접했는데, 그 중 메서드 오버라이딩(Overriding)오버로딩(overloading) 이 이름은 비슷하지만 전혀 다른 개념이라 두고두고 헷갈려하다 이제서야 정리하는 글이다.

 

 

메서드 오버라이딩(Overriding) - 상속이 이루어져야 성립


  • '메서드 재정의' 라고도 한다.
  • 클래스를 상속받은 자식 클래스에서 상속받은 메서드를 필요에 따라 수정하거나 확장시키는 것이다.
  • 상속받은 메서드의 변수, 기능, 구조 등을 자식 클래스에서 목적에 맞게 변형하여 사용할 수 있다.
# 부모 클래스
class Graduation :
    def bachelor(self, name) :
        return "축졸업 !!" + name + '\n(*/ω\*)척척학사\(〇_o)/'
    
    def master(self, name) :
        return False

# 자식 클래스
class Graduation_2(Graduation) :
    def master(self, name) : 
        return "축졸업 !!" + name + '\n(*/ω\*)척척석사\(〇_o)/'

result = Graduation().master('홍길동')
result_2 = Graduation_2().master('홍길동')
print('부모 클래스 -->', result)
print('자식 클래스 -->\n', result_2)

>>>
부모 클래스 --> False
자식 클래스 -->
 축졸업 !!홍길동
(*/ω\*)척척석사\(〇_o)/

위 코드는 내가 졸업할 때 친구들이 졸업 축하 현수막에 넣은 코드를 조금 변형해서 재탕한 것이다. 고마워유 하*, 지*, 동* ㅎㅎ

 

Graduation 클래스를 상속받는 자식 클래스인 Graduation_2에서 master 메서드를 수정하여 호출하면 부모 클래스의 master 메서드 반환 결과는 'False'지만, 자식 클래스의 결과는 졸업 축하 메시지로 출력된다.

 

클래스 상속은 같은 기능을 효율적으로 활용하기 위함이므로 자식 클래스에서 따로 bachelor 메서드를 정의해주지 않아도 자동으로 상속된다. 자식 클래스의 쓰임에 맞는 수정이 필요한 master 메서드만 따로 재정의한게 오버라이딩(Overriding)이라고 한다.

 

 

 

메서드 오버로딩(Overloading) - 상속과 1도 관계없음


  • 오버라이딩과 다르게 상속과 관계없는 개념이다. 
  • 동일한 클래스 내에서 같은 이름의 메서드를 여러 개 생성할 수 있다. 매개변수의 개수, 타입에 따라서 자동적으로 매개변수와 인수를 매칭하여 호출하고자 하는 메서드를 호출한다.
  • 하나의 메서드에 다형성을 부여한다.
  • 파이썬은 공식적으로 오버로딩을 지원하지 않으나, 변칙적으론 구현 가능하다. 자바는 오버로딩 가능

 

1. 가변인자 ( *args, **kwargs )

오버로딩을 쓰는 이유가 같은 기능을 하더라도 매개변수를 다양하게 두고 싶어서이다.

파이썬은 오버로딩을 지원하지 않지만 가변인자를 이용하면 오버로딩을 구현할 수 있다.

가변인자는 말 그대로 인수의 개수가 변할 수 있다. 인수의 개수가 100개, 200개가 되어도 상관없다. 아무 변수명 앞에 '*' 를 붙여주면 가변인자가 된다. 값은 튜플로 저장된다!

 

class Graduation :
    def bachelor(self, *name) :
        return "축졸업 !!" + f'{name}' + '\n(*/ω\*)척척학사\(〇_o)/'
    
    def master(self, *name) :
        return False

obj = Graduation()
result = obj.bachelor('홍길동', '이순신')
result_2 = obj.bachelor('홍길동', '이순신', '강감찬', '두루미')

print(result)
print('='*50)
print(result_2)

>>>
축졸업 !!('홍길동', '이순신')
(*/ω\*)척척학사\(〇_o)/
==================================================
축졸업 !!('홍길동', '이순신', '강감찬', '두루미')
(*/ω\*)척척학사\(〇_o)/

위 Graduation 클래스의 메서드인 bachelor의 매개변수에 가변인자를 집어넣었더니 인수가 2개든 4개든 에러없이 잘 출력되는 걸 확인했다.

 

class Graduation :
    def bachelor(self, **name) :
        return "축졸업 !!" + f'{name}' + '\n(*/ω\*)척척학사\(〇_o)/'
    
    def master(self, **name) :
        return False

obj = Graduation()
result = obj.bachelor(name='홍길동', age=25)
result_2 = obj.bachelor(name='홍길동', age=25, major='Communication')

print(result)
print('='*50)
print(result_2)

>>>
축졸업 !!{'name': '홍길동', 'age': 25}
(*/ω\*)척척학사\(〇_o)/
==================================================
축졸업 !!{'name': '홍길동', 'age': 25, 'major': 'Communication'}
(*/ω\*)척척학사\(〇_o)/

이렇게 변수 앞에 별 두 개 '**'를 붙이면 값이 딕셔너리로 전달된다. 키-값 형태로 된 값을 인수로 주면 파이썬이 알아서 변수에 저장하고 딕셔너리를 생성한다. 

참 유용한 기능인듯.

 

2. MultipleDispatch 패키지

cmd에서 python.exe -m pip install multipledispatch 로 패키지를 설치한 후, 메서드 정의 코드 위에 dispatch 어노테이션을 붙여주면 자바처럼 오버로딩이 가능하다. 코드로 보면 이해가 쉽다.

 

from multipledispatch import dispatch

class Graduation :
    @dispatch(str, str)
    def bachelor(self, name1, name2) :
        return "축졸업 !!" + name1 + name2 + '\n(*/ω\*)척척학사\(〇_o)/'
    
    @dispatch(str, str, str)
    def bachelor(self, name1, name2, name3) :
        return "축졸업 !!" + name1 + name2 + name3 + '\n(*/ω\*)척척학사\(〇_o)/'
    
    @dispatch(str, int)
    def bachelor(self, name, age) :
        return "축졸업 !!" + f'{name} : {age}세' + '\n(*/ω\*)척척학사\(〇_o)/'

obj = Graduation()
print(obj.bachelor('홍길동', '이순신'))
print(obj.bachelor('홍길동', '이순신', '강감찬'))
print(obj.bachelor('홍길동', 25))

>>>
축졸업 !!홍길동이순신
(*/ω\*)척척학사\(〇_o)/
축졸업 !!홍길동이순신강감찬
(*/ω\*)척척학사\(〇_o)/
축졸업 !!홍길동 : 25세
(*/ω\*)척척학사\(〇_o)/

오버로딩하고자 하는 자료형을 @dispatch(자료형1, 자료형2) 로 작성하고, 그 아래에 def bachelor(자료형1, 자료형2)로 작성하면 된다.

dispatch 앞에 '@' 을 달면서 컴파일러가 읽을 수 있는 주석을 만들어, 아래에 있는 함수의 파라미터 개수, 파라미터 타입을 미리 명시해주어서 메서드가 호출될 때 자동으로 처리된다.

 

 

반응형