다형성

Python SELF KO
레벨 16 , 레슨 2
사용 가능

8.1 다형성

다형성(Poylmorphism)은 객체지향 프로그래밍(OOP)의 기본 개념 중 하나로, 서로 다른 클래스의 객체들이 동일한 인터페이스를 사용할 수 있도록 해줘.

Python에서 다형성은 동적 타입 지정과 상속을 통해 이뤄져. 다형성의 중요한 측면은 메소드 오버로딩과 기본 클래스의 메소드를 서브 클래스에서 재정의하는 것이야.

다형성의 주요 개념:

다양한 객체를 위한 통일된 인터페이스:

다형성은 다양한 클래스의 객체들이 서로 다른 메소드 구현을 가질 수 있는 통일된 인터페이스를 사용할 수 있게 해줘.

동적 타입 지정:

Python에서는 변수의 타입이 런타임 동안에 결정되기 때문에, 요구하는 인터페이스를 지원하는 모든 클래스의 객체와 함께 작동할 수 있어.

상속:

클래스 계층 구조를 생성하여 서브 클래스가 기본 클래스의 속성과 메소드를 상속 받고, 특정 기능을 위해 이를 재정의할 수 있게 해줘.

다형성의 예:

간단한 다형성 예시: 세 개의 클래스 모두 move()라는 메소드를 가지고 있어. 이걸 통해 우리는 이 객체들과 동시에 작동할 수 있는 코드를 작성할 수 있지.


class Car:
    def move(self):
        pass
        
class Human:
    def move(self):
        pass
        
class Bird:
    def move(self):
        print("카!")
        
car = Car()
human = Human()
bird = Bird()
        
for it in [car, human, bird]:
    it.move()

여기서 "공통 인터페이스"는 메소드의 이름이거나, 메소드가 인자를 가지고 있다면 그 시그니처야.

8.2 메소드 재정의

다형성은 자주 상속과 함께 사용되어, 기본 클래스가 공통 인터페이스를 정의하고, 하위 클래스가 특정 세부 사항을 구현하는 클래스 계층을 만들어.


class Employee:
    def get_salary(self):
        return 1000
        
class FullTimeEmployee(Employee):
    def get_salary(self):
        return 5000
        
class PartTimeEmployee(Employee):
    def get_salary(self):
        return 3000
        
class Intern(Employee):
    pass
        
def print_salary(employee):
    print(employee.get_salary())
        
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
        
for employee in employees:
    print_salary(employee)

이 예시는 앞의 예시와 비슷하지만 중요한 차이점을 가지고 있어 — 우리 클래스들은 get_salary 메소드를 가질 필요가 없어, 왜냐면 기본 클래스에 항상 존재하니까. 이제 모든 클래스의 "공통 인터페이스"는 단순한 get_salary() 메소드가 아니라, Employee 클래스 전체와 그 모든 메소드와 속성이야.

8.3 서브 클래스 메소드 호출

아래 코드를 잘 봐:

우리는 기본 클래스 Employee에만 있는 print_salary() 메소드를 호출하고, 그것이 기본 클래스의 다른 메소드인 get_salary()을 호출해. 그래서 화면에 어떤 급여가 출력될까?


class Employee:
    def print_salary(self):
        salary = self.get_salary()
        print(salary)
        
    def get_salary(self):
        return 1000
        
class FullTimeEmployee(Employee):
    def get_salary(self):
        return 5000
        
class PartTimeEmployee(Employee):
    def get_salary(self):
        return 3000
        
class Intern(Employee):
    pass
        
employees = [FullTimeEmployee(), PartTimeEmployee(), Intern()]
        
for employee in employees:
    employee.print_salary()

중요! 아래에 적힌 내용을 읽어봐 — 이건 중요해.

만약 print_salary() 메소드를, 예를 들어 FullTimeEmployee 클래스에 대해서 호출하면, 해당 메소드는 클래스에 선언된 것이 없기 때문에 기본 클래스의 메소드가 호출될 거야.

하지만 이 print_salary() 메소드는 FullTimeEmployee 타입의 self 객체에서 get_salary() 메소드를 호출할 거야, Employee가 아니라. 그래서 FullTimeEmployee 클래스의 get_salary() 메소드가 호출되게 돼!

게다가, FullTimeEmployee 클래스는 필요에 따라 기본 클래스의 get_salary() 메소드를 호출할 수 있어. 예를 들어, 우리는 기본 급여에서 퍼센트로 급여를 계산하고 싶을 수도 있어:


class FullTimeEmployee(Employee):
    def get_salary(self):
        base_salary = super().get_salary()
        return base_salary * 5  
      
  
      
  
# 500%
class PartTimeEmployee(Employee): def get_salary(self): base_salary = super().get_salary() return base_salary * 3 # 300%

8.4 메소드 오버로딩

Python에서 메소드 오버로딩(method overloading)은 동일한 이름이지만, 다른 인자를 가진 여러 메소드를 생성할 수 있는 능력이야. 하지만 Python에서는 다른 언어(C++나 Java)를 사용하는 것처럼 메소드 오버로딩이 순수하게 지원되지 않아.

Python에서는 기본 인수, *args 그리고 **kwargs를 사용하여 메소드 오버로딩을 흉내낼 수 있어.

메소드 오버로딩 예시

전달된 인수의 수에 따라 다른 동작을 하는 함수를 구현할 수 있어. 이걸 여러가지 방법으로 할 수 있는데, 예를 들어:


class Example:
    def display(self, a=None, b=None):
        if a is not None and b is not None: print(a, b)
        elif a is not None: print(a)
        else: print("인수 없음")
        

obj = Example()
obj.display(1, 2)  # Output: 1 2
obj.display(1)  # Output: 1
obj.display()  # Output: 인수 없음

전달된 데이터 유형도 고려할 수 있어 — 타입 검사를 통해서 간단하게:


class Example:
    def mod(self, a, b):
        if type(a) == int and type(b) == int: print(a % b)
        elif type(a) == float or type(b) == float: print(round(a / b))
        else: print("도움말: a와 b는 int 또는 float이어야 합니다.")
        

obj = Example()
obj.mod(5, 2)  # Output: 1
obj.mod(5.0, 2)  # Output: 2
obj.mod("5", 2)  # Output: 도움말: a와 b는 int 또는 float이어야 합니다.

잘못된 데이터 유형이 전달된 경우, 도움말이나 심지어 인터넷 문서 링크를 출력할 수 있어 — 이것도 매우 인기 있는 해결책 중 하나야.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION