본문 바로가기
Programming/Java

[Java] 14. 다형성 (Polymorphism)

by Rayched 2023. 1. 20.

1. 개요

이번에 정리한 것은 자바, 객체 지향 프로그래밍 언어로써 가지는 특징 중 하나인

'다형성'에 대한 것이다.

처음에는 객체 지향 프로그래밍 언어 특징 전체를 정리한 게시글에

이 내용을 추가하는 것을 고려해 봤지만 정리를 하다 보니

처음에 생각한 것보다 분량이 많아서 그냥 개별적으로 추가하기로 했다.

객체 지향 프로그래밍 언어에 대해 정리한 것은 아래 링크를 통해서 확인하면 될 것이다.

https://rclogstorage.tistory.com/m/14

 

[Java] 0 - (1). 객체 지향 프로그래밍이란 무엇인가

앞에서 자바의 정의와 특징들을 설명할 때, 자바의 특징인 '객체지향 언어'라는 부분에 대해 설명하지 않고 넘어갔었다. 이번에는 객체 지향 언어, 객체 지향 프로그래밍에 대해 정리해보겠다.

rclogstorage.tistory.com

 

그러면 이제 다형성이란 무엇인지에 대해 알아보자.


2. 다형성 (Polymorphism)

① 다형성의 정의

  - 객체가 여러 가지 형태로 표현될 수 있는 능력

  - 부모 타입의 참조 변수로 자식 클래스의 객체를 다룰 수 있는 것 (다형성의 예시)

 

② 다형성 예제

다형성이란 "부모 타입의 참조 변수로 자식 클래스의 객체를 다루는 것"이라고 알았으니

이제 예제를 통해서 이 개념을 증명해 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//다형성
 
public class Main {
  public static void main(String[] args){
      동물 a동물 = new 동물();
      a동물.숨쉬다();
      
      동물 b동물 = new 원숭이();
      b동물.숨쉬다();
      
      동물 c동물 = new 사람();
      c동물.숨쉬다();
  }
}
 
class 동물 {
  void 숨쉬다(){
    System.out.println("동물이 숨을 쉽니다.");
  }
}
 
class 원숭이 extends 동물 {
  void 숨쉬다(){
    System.out.println("원숭이가 숨을 쉽니다.");
  }
}
 
class 사람 extends 동물 {
  void 숨쉬다(){
    super.숨쉬다(); 
    //부모로부터 상속받은 원본 메서드를 실행시킨다.
    //재정의를 했다고 해서 원본이 사라지는 것은 아님.
    System.out.println("사람이 숨을 쉽니다.");
  }
  
  void 말하다(){
    System.out.println("사람이 말을 합니다.");
  }
}
 
 
 
 
 
cs

프로그램 실행 결과

프로그램을 실행하면 위와 같은 문장이 출력되는 것을 확인할 수 있을 것이다.

즉, 부모 타입의 참조 변수로 자식 객체의 메서드를 실행하는 것이 가능하다는 것이 증명된 것이다.

그러면 왜 이러한 결과가 나왔을까?

그 이유를 알기 위해서 예제 코드를 확인해 보자.

 

(1). 부모 타입 참조변수로 자식 객체의 메서드 실행하기 (오버라이드한 메서드 실행)

상속 관계 요약본
상단의 소스 코드 상의 상속 관계는 위의 그림을 참고하면 된다.

 

해당 코드는 부모 타입의 참조변수에 자식 객체를 연결하고

자식 객체에서 오버라이드한 메서드를 실행시키는 역할을 한다.참조 변수는 일종의 객체를 조종하는 리모컨이다.이 리모컨은 부모 클래스인 '동물' 타입의 변수로'숨쉬다()' 메서드를 실행시키는 것이 가능하기 때문에자식 객체인 '원숭이'나 '사람'의 오버라이드한 '숨쉬다()' 메서드도 실행될 수 있는 것이다.

 

그러면 부모 타입의 참조 변수가 자식 객체에서 추가한 메서드를 실행하는 것이 가능할까?해당 부분에 대한 것은 추가적으로 좀 더 찾아본 다음에 올리는 것으로 하고이번에는 불가능하다고 정하고 글을 쓰도록 하겠다.

 

(2). 부모 타입 참조변수로 자식 객체의 메서드 실행하기 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//다형성
 
public class Main {
    public static void main(String[] args){
        동물 c동물 = new 사람();
        c동물.말하다(); //error
    }
}
 
class 동물 {
    void 숨쉬다(){
        System.out.println("동물이 숨을 쉽니다.");
    }
}
 
class 사람 extends 동물 {
    @Override
    void 숨쉬다() {
        super.숨쉬다();
        System.out.println("사람이 숨을 쉽니다.");
    }
 
    void 말하다(){
        System.out.println("사람이 말을 합니다.");
    }
}
cs

동물 타입의 참조 변수 c동물로, 사람 객체의 '말하다()' 메서드를 실행하려고 한다.

프로그램은 실행되지 않고, 컴파일 에러가 발생하게 된다.

 

앞에서 말했듯이 참조 변수는 일종의 리모컨으로

부모 클래스인 '동물'이 '숨쉬다()' 메서드를 가지고 있지만

자식 클래스인 '사람'에서 정의한 '말하다()' 메서드는 가지고 있지 않다.

따라서 해당 문장을 입력하면 컴파일러는 '부모' 클래스에서 해당 메서드를 찾겠지만

당연히 그 메서드는 존재하지 않기 때문에 컴파일 에러가 발생하게 된다.

 

컴파일러의 입장에서는 '부모' 클래스에서 존재하지 않은 메서드를 실행하라는 명령을 들은 것이기에

프로그램을 실행하지 않고, 에러 메시지를 통해서 개발자에게

해당 문장이 잘못됐고 이를 수정하라고 알려주게 된다.

 

③ 최종 정리

- 부모 클래스의 참조 변수에 자식 객체 연결가능

  단, 자식 클래스에서 정의된 멤버를 활용하지는 못한다.

 

- 자식 클래스의 참조 변수에 부모 객체는 연결할 수 없다.

  자식 클래스의 맴버 수가 부모 객체보다 더 많기 때문에 연결이 불가능하다.


3. 마치며

객체 지향 프로그래밍 언어의 특징인 다형성을 정리한 내용은 여기서 끝이 났다.

정리한 내용을 다시 가공을 해서 글을 쓰다 보니 느낀 것은 아직 부족한 점이 많이 남았다는 것이다.추후에 부족한 점에 대해 파악하고, 보충 내용을 추가하도록 하겠다.

'Programming > Java' 카테고리의 다른 글

[Java] 15. 추상 클래스  (0) 2023.01.26
[Java] 13. 오버로딩 (Overloading)  (0) 2023.01.17
[Java] 12. 캡슐화와 접근 제어자  (0) 2023.01.16
[Java] 11. 생성자 (Constructor)  (0) 2023.01.16
[Java] 10. 상속 (Inheritance)  (0) 2022.12.22