인터페이스(Interface)에 대한 설명은 항상 모호하고 장황합니다. (클래스는 더 하죠)
그냥 ‘어떤 메소드를 가지고 있는지 알려주는 것’ 정도로 이해하면 됩니다.

1
2
3
4
5
public interface IPlayer {
    void play();
    void pause();
    void stop();
}

이제, IPlayer를 구현(implements)한 클래스는 play, pause, stop 메소르를 가지고 있다는걸 알 수 있습니다.

“좋아요. 쉽네요. 근데, 왜 쓰죠? 이유를 알면 좋겠어요.”

네. 알아 보죠. (-:
1. 혼자 개발하는 사람은 메소드를 다 알고 있으니 인터페이스를 만들 필요가 없겠죠. 하지만, 불특정 다수가 쓴다면 어떨까요. 문서로 제공할 수 있지만 그냥 인터페이스를 통해 알려주는게 편리합니다. 이클립스 등의 IDE를 쓰면 코드 힌트가 뜨니까요.

2. 경험해본 사람들의 이해를 도울 수 있습니다. 예를 들어, 플레이어라는 인터페이스(IPlayer)를 만들면 재생, 일시정지, 정지 등의 기능이 일반적으로 다 들어 있죠. 어떤 새로운 기기를 받았을 때 ‘플레이어가 구현되어 있다’는 말을 들으면 즉각적으로 ‘재생, 일시정지, 정지’가 되겠다는걸 알게 되는 것입니다. 프로그래머도 마찬가지겠죠. 대충 ‘어떤 메소드가 있구나’ 하는걸 알게 됩니다. ‘추상화되었다’라고 말할 수 있죠.

3. 코드가 단순해 집니다. MP3Player라는 클래스를 만들고 객체를 생성해 볼께요.

1
2
3
4
5
6
7
8
9
10
11
public class MP3Player {
    public void play() { }
    public void pause() { }
    public void stop() { }
}

public void play(MP3Player player) {
    player.play();
}

play(new MP3Player());

만약, WonHadaPlayer를 추가로 만들면 아래와 같이 될거에요.

1
2
3
4
5
6
// 새로운 메소드 추가
public void play(WonHadaPlayer player) {
    player.play();
}

play(new WonHadaPlayer());

그런데 만약, 내 코드를 외부에 공개해서 다른 사람이 써야 한다면 어떨까요? 그들이 만드는 클래스를 알 수 없으니 메소드를 미리 추가할 수 없겠죠? 이럴 때 인터페이스를 사용하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// IPlayer 구현 (WonHadaPlayer도 동일하게 구현)
public class MP3Player implements IPlayer {
    @Override
    public void play() { }

    @Override
    public void pause() { }

    @Override
    public void stop() { }
}

public void play(IPlayer player) {
    player.play();
}

play(new MP3Player());
play(new WonHadaPlayer());

이제 어떤 새로운 클래스가 생겨도 문제 없습니다. (-: