레이블이 오버로딩인 게시물을 표시합니다. 모든 게시물 표시
레이블이 오버로딩인 게시물을 표시합니다. 모든 게시물 표시

2017. 1. 11.

폴리모피즘(2) 메소드 오버로딩의 한계


 
메소드 오버로딩의 한계
 
Player 클래스는 바이올린과 플룻을 연주할 수 있습니다.


만약 연주악기가 추가 된다면 어떻게 될까요? 피아노가 추가된다면
 
package instrument;
public class Piano {
             public void sound() {
                           System.out.println("play the piano");
             }
}
예제 4 - 4 Piano.java
 
instrument 패키지에 Piano클래스가 추가되었습니다. Piano클래스가 추가되어서
연주자가 피아노를 연주할 수 있었으면 좋겠는데, 어떻게 하면 좋을까요?
일단 메소드 오버로딩 생각해 볼수 있겠습니다.
 
import instrument.*;
public class Player {
             . . .
             public void play(Piano p) {
                           p.sound();
             }
}
예제 4 - 5 Player.java
 
예제 4 - 3 Player.java 의 내용에 public void play(Piano p)를 추가했습니다.
 
악기가 또 추가 되었습니다.
package instrument;
public class Guitar {
             public void sound() {
                           System.out.println("play the guitar");
             }
}
예제 4 - 6 Guitar.java
 
Player클래스로 하여금 기타도 연주하게 하고 싶습니다. 어떻게 할까요?
물론 메소드 오버로딩을 할 수 있습니다. 하지만 이쯤 되면 느끼셨겠지만 악기가 추가 될때
마다 메소드 오버로딩을 이용해서 계속 메소드를 추가하는 형태로 Player클래스를 설계
한다면 악기가 추가 될때마다 Player 클래스도 변경이 되어야 합니다.
악기가 추가 될때 마다 추가되는 악기에 대한 메소드를 만들어 주지 않으면 연주자는
추가된 악기를 연주할 수 있는 방법이 없으니까요.
더구나 앞으로 악기가 계속해서 추가 되는 상황이라면 메소드 오버로딩을 이용한 설계는
절대로 바람직하지 않습니다. 언제 다시 수정해야 할 상황이 올지 모르니까요.
연주자와 연주악기의 관계에 있어서 연주자가 자신이 연주하는 악기에 대한 구체적인
정보를 알고 있어야 연주를 할 수 있다면, 연주자와 연주악기 사이에는 직접적인 관계가
설정이 됩니다.  자바로 설명을 하자면 Player클래스에서 연주할 Violin이나, Guitar등의
데이터형을 사용하게 되면, Player클래스와 Violin, Guitar 클래스 간에는 직접적인 관계가
생긴다는 뜻입니다.
Player클래스에서 연주악기인 Violin 클래스, Guitar에 대한 정보가 필요하다는 뜻이고,
이런 정보(Violin 클래스파일, Guitar클래스 파일)를 갖고 있어야만 컴파일이 되니까요.
Player 클래스에서 연주악기를 클래스를 import하는 순간부터 연주자 클래스는 연주악기
클래스와 관계가 생겨나게 됩니다. 그림으로 생각한다면 이렇게 될것입니다.



사용자 삽입 이미지

그림 4 - 1 [ overload uml]


 
Player클래스내에서 Piano클래스,Guitar클래스,Flute클래스,Violin클래스로 화살표가
있는 것은 Piano클래스,Guitar클래스,Flute클래스,Violin클래스를 직접 참조한다는 뜻이고
관계가 있다는 뜻입니다. Piano클래스,Guitar클래스,Flute클래스,Violin클래스가 추후
변경이 된다면 Player클래스도 영향을 받을 가능성도 존재하는 셈입니다.
최악의 상황이겠죠.아마.

폴리모피즘(1) 메소드 오버로딩

 
메소드 오버로딩
 
음악가와 음악가가 다루는 악기들 그러니까 바이올린이라던가 플룻,피아노,첼로등과의
관계는 자바에서 메소드 오버로딩에 관한 개념을 이야기 할 때 좋은 예제가 됩니다.
 
같은 이름의 메소드를 갖고 있는 클래스들
 
음악가는 보통 한 두가지 이상의 연주악기를 다룰 수 있습니다.
대개 피아노를 연주할 수 있으며, 바이올리도 연주할 수 있고, 때로는 플룻도 연주 할 수
있습니다. 음악가는 연주악기가 다르면, 연주악기에 따라 적절하게 연주하는 방법을 바꾸어
가며 해당 연주악기를 연주를 할 수 있습니다.
연주하는 악기가 제각기 다르고,바뀌더라도 음악가가 악기를 가지고 연주를 한다는 그
행위는 항상 같습니다.
이런 개념은 메소드 오버로딩을 활용하는 좋은 예가 됩니다.
 
자바로 음악을 연주하는 연주가와 악기를 만들어 보겠습니다.
 
플룻을 만듭니다.
 
package instrument;
public class Flute {
                           public void sound() {
                                        System.out.println("play the flute");
                           }
}
예제 4 - 1 Flute.java
 
바이올린을 만듭니다.
package instrument;
public class Violin {
                           public void sound() {
                                        System.out.println("play the violin");
                           }
}
예제 4 - 2 Violin.java
 
플룻과 바이올린 클래스는 특별한 것은 없고, 모두 sound()라는 메소드가 있는데
호출하게 되면 플룻은 플룻소리를 내고, 바이올린을 바이올린 소리를 냅니다.
실제로 소리를 내면 좋겠지만 형편상 소리 내는 것 대신 메시지를 화면에 출력을 합니다.
 
연주자를 만들어 보겠습니다.
연주자는 악기를 연주할 수 있으니까 play라는 이름으로 메소드를 가지는게 어울리겠지요.
 
import instrument.*;
public class Player {
             public void play(Violin v) {
                           v.sound();
             }
             public void play(Flute f) {
                           f.sound();
             }
             public static void main(String[] args) {
                           Player player = new Player();
                           player.play(new Flute());                  // Flute 를 연주합니다.
                           player.play(new Violin());                 // Violin을 연주합니다.
             }
}
예제 4 - 3 Player.java
 
Player 클래스는 play 메소드를 통해서 해당 악기의 소리를 냅니다.
연주자는 플룻도 연주할 수 있고, 바이올린도 연주할 수 있기 때문에 메소드 오버로딩을
통해서 play 라는 이름하나로 여러가지의 악기를 연주할 수 있게 해놓았습니다.
 
만약 메소드 오버로딩을 사용하지 않는다면 play 라는 이름을 여러 개로 나누어
void playViolin(Violin v), void playFlute(Flute v)등으로 play라는 메소드를 여러 개의
이름으로 나누어야 합니다.
 메소드 오버로딩을 사용하면  프로그램의 가독성(readability)이 상당히 좋아 지고,
메소드 이름을 일관되고,직관적으로 생각할 수 있게 끔 만들 수 있습니다.
Player 클래스는 play 메소드에 Violin이 인자로 오거나 Flute가 인자로 오거나 어떤
경우라도 적절히 연주할 수 있습니다. Violin이 인자로 오게되면 public void play(Violin v)
메소드가 호출이되고, Flute가 인자로 오게 되면 public void play(Flute f)메소드가 호출
됩니다. 자바 버추얼 머신이 오버로딩된 메소드 인자에 오는 데이터형 정보에 따라서
동적으로 가장 적절한 메소드를 호출해주기 때문입니다.


 

사용자 삽입 이미지

 
 그림 4 - 1 [compile run (Violin.java Flute.java Player.java) ]