상세 컨텐츠

본문 제목

Object Oriented Programming 원칙 (4) - 다형성(polymorphism)

개발/python-객체지향프로그래밍(OOP)

by Matthew0633 2022. 5. 20. 22:12

본문

다형성 Polymorphism

polymorphism is the provision of a single interface to entities of different types[1] or the use of a single symbol to represent multiple different types.

다형성이란, (1) 변수, 메소드, 함수 등이 서로 다른 개체들의 일부로 동시에 속할 수 있게하거나, (2) 다양한 자료형을 가질 수 있도록 추상적인 이름을 사용하는 패턴을 의미한다.

(1) 변수, 메소드, 함수 등이 서로 다른 개체들의 일부로 동시에 속하는 패턴

Korean 과 English 는 say_hi() 라는 동일이름의 메소드를 가지며, 각기 다른 기능 문자열을 출력하는 기능을 수행한다.

class Korean:
    def say_hi(self):
        print("안녕하세요")


class English:
    def say_hi(self):
        print("hello")

(2) 다양한 자료형을 가질 수 있도록 추상적인 이름을 사용하는 패턴

아래의 display_single(), display_multi() 와 같이 인자의 정보가 상이할 경우, 이를 반영하여 함수명을 정의할 경우, 경우의 수에 따라 비슷하게 함수명을 바꿔주며 정의해야 하므로 naming 에 대해 비효율성이 발생한다. 사용 시에도 비슷한 함수명이 많아 인자정보에 따라 기억해야할 name 이 많아진다. 이를 피하기 위해 자료형과 상관없는 추상적인 naming 을 사용할 수 있다.

JAVA에서는 동일한 이름이지만 인자의 type 이 다를 경우 메소드 오버로딩을 사용해야해서 상속이 아닌 경우, 코드 작성량은 동일하다. (메소드 오버로딩에 대해서는 아래에서 좀 더 다루겠다) 그러나 개발 단계에서 naming 에 대한 효율과 사용 시 naming 기억에 대한 효율이 개선된다. 아래에서는, 구조와 기능은 약간 상이한 display_single(), display_multi() 메소드 를 display 라는 동일한 이름으로 정의하여 추상성을 높였다.

class Polymorphic{
    //private static void display_single(int a){
    //    System.out.println("(int) a = " + a);
    //}

    //private static void display_multi(int a, int b){
    //    System.out.println("Arguments: " + a + " and " + b);
    //}

    private static void display(int a){
        System.out.println("Arguments: " + a);
    }

    private static void display(int a, int b){
        System.out.println("Arguments: " + a + " and " + b);
    }

    public static void main(String[] args) {
        display(1);
        display(1, 4);
    }
}

python 에서도 이러한 패턴을 사용할 수 있지만, 메소드 오버로딩을 지원하지 않아, 하나의 display() 내에서 타입과 기능에 따라 분기처리를 해주어야 한다. 대신 코드의 양은 더욱 간결해진다.

class Polymorphic:

    def __init__(self, a: int, b: Optional[int]):
        self.a, self.b = a, b
		
    def display(self) -> None:
        if b == None:
          print("Arguments: " + a)
        else:
          print("Arguments: " + a + " and " + b)

    # def display_single(self): 
    #	  print(f"Arguments: {a}")

    # def display_multi(self): 
    #	  print(f"Arguments: {a} and {b}")

print(Polymorphic(1).display())     # Arguments: 1
print(Polymorphic(1, 2).display())  # Arguments: 1 and 2

 

 

메소드 오버라이딩 (Method Overriding)

Method overriding, in object-oriented programming, is a language feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. It allows for a specific type of polymorphism (subtyping).

다형성을 적용된 방법 중 하나로, 상속관계에서 사용되는 메소드 오버라이딩이 있다. 이는 자식 class 에서 부모 class 의 메소드를 가져와 동일한 이름과 구조를 유지하며, 일부 기능을 추가하거나 혹은 다른 기능을 재정의하여 사용하는 것을 의미한다.

파이썬에서도 메소드 오버라이딩을 지원하고 있어 Wiki의 예시를 인용하였다. 하위 class 에서의 메소드인 Advice.message() 가 warning 메시지를 추가 출력하도록 상위 class 의 메소드인 Thought.message() 를 오버라이딩 하고 있다.

class Thought:
    def __init__(self) -> None:
        print("I'm a new object of type Thought!")
    def message(self) -> None:
        print("I feel like I am diagonally parked in a parallel universe.")

class Advice(Thought):
    def __init__(self) -> None:
        super(Advice, self).__init__()
    def message(self) -> None:
        """ 
        [메소드 오버라이딩 구현]
        부모 class Thought.message() 내용 출력 이전에 warning 메세지를 
        추가적으로 출력한다.
        """
        print("Warning: Dates in calendar are closer than they appear")
        super(Advice, self).message()

 

메소드 오버로딩 (Method Overloading, function overloading)

In some programming languages, function overloading or method overloading is the ability to create multiple functions of the same name with different implementations.

함수 오버로딩 또한 다형성을 구현한 예이며, 해당 기능은 Python 에서는 지원하지 않는다. 함수 오버로딩은 동일한 이름이지만 다른 구조를 가지고 있는 함수를 여러 개 정의하고 사용할 수 있는 기능이다. 파라미터의 타입과 수가 달라야 한다는 조건이 있는데 그래야 사용 시에 구별될 수 있기 때문이다.

위에서 본 JAVA 예시코드를 다시 가져왔다. 파라미터의 수나 type 정보가 다른 display 메소드를 각각 정의하고, 각각의 구조에 맞게 호출하여 사용할 수 있다.

class MethodOverloading{

    private static void display(int a){
        System.out.println("Argument(int) : " + a);
    }

    private static void display(int a, int b){
        System.out.println("Arguments(int) : " + a + " and " + b);
    }

	private static void display(double a){
        System.out.println("Argument(double) : " + a);
    }

    public static void main(String[] args) {
        display(1);
        display(1, 4);
        display(1.0);
    }
}

 

<Reference>

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

https://en.wikipedia.org/wiki/Method_overriding#:~:text=Method

https://en.wikipedia.org/wiki/Function_overloading

https://www.programiz.com/java-programming/method-overloading#:~:text=In

https://www.java67.com/2012/10/difference-between-polymorphism-overloading-overriding-java.html

관련글 더보기

댓글 영역