Dev&Ops/Java

[Java] 객체지향의 특징(1) - 다형성(Polymorphism)

zeroneCoder 2022. 1. 29. 19:15

안녕하세요! zerone-code입니다.

 

이번 글에서는 객체지향 프로그래밍(OOP)의 특징인 다형성을 다뤄보고자 합니다.

 

다형성은 OOP의 다른 특징인 추상화, 상속, 캡슐화를 이해함에 있어서 중요한 개념입니다.

 

저도 학부 때 다형성에 대해 와닿지 않은 개념이지만 실무를 하면서 많이 와닿게 된 개념입니다.

 

이 글을 읽으시는 분들은 완벽히 이해하고 가셨으면 좋겠습니다 :)

 

1. 다형성이란?

다형성이란 하나의 객체(Object) 혹은 메서드가 여러 가지 타입을 가질 수 있는 것을 말합니다.

 

이렇게 정의만 읽어봐서는 확 와닿지 않으실 겁니다.

 

Parent와 Child 클래스 예제를 이용해서 설명해보도록 하겠습니다.

위의 코드를 보시면 클래스 구조는 Chlid 클래스는 Parent 클래스를 상속받는 클래스입니다.

먼저 Child 클래스는 Parent 클래스로부터 상속받아서 printClass라는 메서드를 재정의했습니다.

그리고 매개 변수와 리턴형이 다른 printClass 메서드를 확인할 수 있습니다.

이런 특징이 위에서 설명드린 메서드가 여러 가지 타입을 가질 수 있는 것을 말합니다.

 

위 두 클래스를 호출하고 있는 Polymorphism 클래스의 main 메서드를 한번 살펴보겠습니다. 

Line 21 ~ 25번을 보시면 Parent라는 클래스는 자기 자신의 객체를 참조하기도 하면서, Child의 객체를 참조할 수도 있습니다. 

이런 특징이 위에서 설명드린 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 말합니다.

 

main 메서드를 실행하면 결과가 어떻게 나올까요?

위 와 같은 결과를 확인할 수 있습니다.

 

오류 메시지를 보시면 Line 33번째에 Child 클래스 형으로 Parent 클래스 객체를 참조하려는 과정에서 발생한 오류인 것을 확인할 수 있습니다.

이처럼 부모 클래스(Parent Class)는 자식 클래스(Child Class)로 생성된 객체를 참조할 수 있지만 반대의 상황에서는 안된다는 것을 알 수 있습니다.

 

이 정도면 다형성에 대한 대략적인 감이 잡히셨을 겁니다.

 

그럼 다형성과 관련 있는 기능인 오버라이딩과 오버 로딩에 대해 알아보도록 하겠습니다.

 

2. 오버 라이딩(Overriding)과 오버 로딩(Overloading)

다형성을 이해하려고 하시는 분들이라면 오버 라이딩(Overriding)과 오버 로딩(Overloading)이라는 개념을 반드시 보게 될 것입니다.

이 두 가지 개념은 저도 면접을 볼 때 많이 받아본 질문 중 하나일 정도로 중요하다고 생각됩니다.

각 개념에 대한 정의와 예제로 설명해보겠습니다.

 

오버 라이딩(Overriding)

    • 부모 클래스(상위 클래스)로부터 상속받은 메서드를 자식 클래스(하위 클래스)에서 재정의해서 사용한다.
    • 즉, 부모 클래스(상위 클래스)에 정의된 함수일지라도 자식 클래스(하위 클래스)에서 동일한 return, 동일한 이름, 동일한 접근제어자로 덮어쓰기(Override)를 하여 그 기능을 사용한다는 뜻입니다.
    • 아래 예제에서 보시다시피 Child 클래스에서는 Parent 클래스의 printClass 메서드를 동일한 return, 동일한 이름, 동일한 접근제어자로 내부 구현만 재정의 하고 있는 것을 확인할 수 있습니다.
    •  

 

  • 오버 라이딩의 제약사항
    • 자식 클래스(하위 클래스)에서 재정의하는 메서드의 접근 제어자는 부모 클래스(상위 클래스)의 메서드보다 좁게 설정할 수 없다.
      • 즉, 부모 클래스에서 protected로 정의된 메서드라면 자식 클래스에서는 그보다 큰 범위로 public으로 정의할 수 있다.
    • 자식 클래스(하위 클래스)에서 예외(Exception)는 부모 클래스(상위 클래스) 보다 더 큰 범위의 예외(Exception)를 선언할 수 없다. 

오버 로딩(Overloading)

  • 하나의 클래스에 같은 이름의 함수(메서드)를여러 개 정의하고, 매개변수의 유형과 개수를 다르게 하여 사용한다.
  • 즉, 하나의 함수 이름으로 여러 매개 변수 타입을 넣어서 사용한다는 뜻입니다.
  •  
  • 오버 로딩이 안 되는 경우 : return값만 다른 경우, 접근제어자만 다른 경우
  • 오버 로딩을 사용하는 이유?
    • 같은 기능을 하는 메서드를 하나의 이름으로 사용할 수 있다.
    • 메서드의 네이밍 고민을 줄일 수 있다.

 

3. 정리

  1. 다형성하나의 객체(Object) 혹은 메서드가 여러 가지 타입을 가질 수 있는 것
  2. 오버 라이딩은 상위 클래스를 상속받은 하위 클래스에서 메서드를 재정의 해서 사용하는 것 
  3. 오버 로딩은 하나의 함수 이름으로 여러 매개 변수 타입을 넣어 사용하는 것
    구분 오버 라이딩(Overriding) 오버 로딩(Overloading)
    적용 범위 상속 관계 같은 클래스 내
    메서드 이름 부모 클래스와 자식 클래스 동일 부모 클래스와 자식 클래스 동일
    매개 변수 부모 클래스와 자식 클래스 동일 부모 클래스와 자식 클래스 다름
    리턴 타입 부모 클래스와 자식 클래스 동일 부모 클래스와 자식 클래스 다름
    접근 제어자 자식 클래스가 부모 클래스보다 넓은 범위 가능  모든 접근제어자 가능

 

Additional Information

** 위 소스 코드에서 등장한 @Override는 어떤 용도인가?

  • 어노테이션(Annotation)이라는 것으로 일반적인 주석과 다르게, 검증하는 기능을 한다.
  • 여기서 사용된 @Override라는 어노테이션은 오버 라이딩을 검증하는 기능을 한다.
  • 코드상으로 검사했을 때 오버 라이딩이 실제로 시행되지 않았다면 컴파일 시 오류를 출력한다.

 

다음 글에서는 객체지향 프로그래밍(OOP)의 특징, 2번째로 캡슐화에 대해 다뤄보도록 하겠습니다.

 

잘 읽으셨다면 많은 공감 부탁드립니다!