코린이의 소소한 공부노트

인터페이스의 장점 본문

Java

인터페이스의 장점

무지맘 2022. 5. 13. 15:11

1. 두 대상(객체) 간의 연결을 돕는 중간 역할을 한다.

  - 사람은 인간의 언어를 사용하고, 컴퓨터는 기계어를 사용한다. 서로의 말을 이해하지 못하지만, 우리는 컴퓨터를 쉽게 사용한다. 여기서 인터페이스(껍데기)는 GUI(Graphic User Interface)이다. GUI가 화면에 띄운 아이콘을 누르거나 키보드로 입력을 함으로써 컴퓨터 언어, 내부(알맹이)를 몰라도 사람이 컴퓨터를 사용할 수 있게끔 해 준다.

2. 변경에 유리한 설계를 하게 해 준다.

  - 그래픽 카드를 바꾸거나 RAM카드를 바꾸는 등 컴퓨터 내부(알맹이)의 변화가 생겨도 GUI(껍데기)를 이용해 얼마든 사용할 수 있기 때문에 사용자는 컴퓨터 내부 변화에 크게 영향받지 않는다.

3. 선언(설계)과 구현을 분리시킬 수 있게 한다.

 1) 껍데기 + 알맹이 -> 변경에 불리하다. (= 유연하지 않다. 강한 결합)

class In{
    public void answer(){
        System.out.println("치킨");
    }
}

class Me{
    public void question(In i){
        i.answer();
    }
}

In 클래스에는 answer() 메서드가 있고, Me 클래스에서는 In 타입의 객체를 매개변수로 받아 In 클래스의 메서드 answer()를 호출하는 question() 메서드가 있다. 두 클래스는 직접적인 관계가 있다고 볼 수 있다. 

// 메인
Me m = new Me();
m.question(new In());
// "치킨"

여기에서 In클래스 대신 새로운 클래스 In2를 사용한다고 해보자. 그러면 이제 Me클래스와 In2클래스가 직접적인 관계가 되었으니, Me 클래스와 메인에 수정해야 할 부분이 생긴다.

class In2{ // 새 클래스
    public void answer(){
        System.out.println("김치부침개");
    }
}

class Me{
    public void question(In2 i){ // 매개변수의 타입을 바꿔야 한다.
        i.answer();
    }
}

// 메인
Me m = new Me();
m.question(new In2()); // 수정
// "김치부침개"

큰 변화가 일어난 것은 아니지만, 내가 쓰고자 하는 클래스(알맹이)가 바뀔 때마다 매번 코드를 수정해줘야 하니 귀찮다.

 2) 껍데기 - 알맹이 분리 -> 변경에 유리하다. (= 유연하다. 느슨한 결합)

interface Out{
    public void answer();
}

class In implements Out{
    public void answer(){
        System.out.println("치킨");
    }
}

class Me{
    public void question(Out o){ // 껍데기와 알맹이를 분리하면서 이 부분을 바꿨다.
        o.answer();
    }
}

이번에는 인터페이스를 활용해 껍데기(Out)와 알맹이(In)를 분리시켰다. 그리고 Me 클래스와 Out 인터페이스를 직접 연결시키고, In 클래스는 간접적으로 연결시켰다.

// 메인
Me m = new Me();
m.question(new In());
// "치킨"

이 상태에서 아까와 똑같이 In2 클래스로 바꿔보겠다.

interface Out{
    public void answer();
}

class In2 implements Out{
    public void answer(){
        System.out.println("김치부침개");
    }
}

class Me{
    public void question(Out o){ // 변화 없음
        o.answer();
    }
}

// 메인
Me m = new Me();
m.question(new In2()); // 수정
// "김치부침개"

In 클래스도 In2 클래스도 모두 Out 인터페이스를 구현한 것이므로, 다형성에 의해 question() 메서드의 매개변수로 In 객체와 In2 객체 모두 사용 가능하다.  그렇기 때문에 Me 클래스에서 수정할 부분이 없어지는 것이다. 이것이 바로 변경에 유리하다는 것이고, 유연하다는 것이다. 이렇게 껍데기와 알맹이를 분리하는 식으로 구현해놓으면 코드 변경이 발생했을 때 수정할 부분도 줄어들고 에러 날 확률도 줄어들게 된다.

4. 개발 시간을 단축시켜준다.

 1) 껍데기+알맹이

  -Me 클래스가 In 클래스를 사용(의존)하고 있었다. Me 클래스를 user, In 클래스를 provider라고 한다면, provider가 완성될 때까지 user는 기다려야 한다.

 2) 껍데기 - 알맹이

  - Me 클래스는 Out 인터페이스와 연결되어있다. 인터페이스는 추상 메서드의 집합이므로 provider인 In 클래스가 완성되어있지 않아도 user는 인터페이스에 선언된 추상 메서드를 보고 코드를 작성할 수 있다. 그 후 provider가 완성되면 user가 인터페이스를 통해 provider에서 구현한 내용을 바로 사용 가능하다.

  - user가 인터페이스를 통해서 접근하는 것이므로 provider의 iv는 캡슐화되어있기 때문에 보호받을 수 있다.

5. 표준화가 가능하다.

  - 인터페이스의 변경이 일어나지 않는 이상, 각기 다른 provider들이 인터페이스에 맞춰서 코딩이 되어있기 때문에 user는 인터페이스를 보면 provider의 변경에 관계없이 사용할 수 있다.

  - 건전지는 표준 규격이 정해져 있으므로, 제조사에 관계없이 사람들은 자기가 원하는 타입을 골라서 살 수 있다.

6. 서로 관계없는 클래스들을 연결해줄 수 있다.

  - 자바에서의 관계는 상속, 구현을 통한 조상-자손 관계뿐이다. 이외의 관계는 존재하지 않는다.

  - 인터페이스를 이용하면 형제, 사촌 관계에 있는 클래스를 연결해줄 수 있다.

6명의 친구들이 에버랜드에 왔다. 날씨가 좋아 사람들이 많아 잘못하면 일행을 놓칠 수 있다는 생각이 들었다. 큰 친구들은 눈에 잘 띄니까 괜찮은데, 춘식, 콘, 빠냐 같이 작은 친구들은 걸어 다니면 안 보여서 날개를 달아주기로 했다.

급한 대로 메서드 오버로딩을 이용해 날개를 만들어주었는데..

void fly(춘식 c){
    // 춘식이에게 날개를 달아준다.
}

void fly(콘 c){
    // 콘에게 날개를 달아준다.
}

void fly(빠냐 b){
    // 빠냐에게 날개를 달아준다.
}

뭔가 조잡한 느낌이 들었다. 그래서 이번에는 다형성을 이용해 날개를 만들어줬는데..

void fly(Kakao k){
   // Kakao의 자손에게 날개를 달아준다.
}

이렇게 하니 춘식이, 콘에게는 날개를 달아줬는데 무지까지 달아주게 됐고, 정작 날개가 필요한 빠냐에게는 못 달아줬다. 6명이 머리를 맞대고 고민을 하고 있었는데, 갑자기 무지에게 번뜩이는 아이디어가 떠올랐다.

무지: 인터페이스를 이용해보는게 어때?

interface Smaller{
    void fly(Smaller s);
}

class 춘식 extends Kakao implements Smaller {
    public void fly(Smaller s) { /* 날개를 달아준다. */ }
}

class 콘 extends Kakao implements Smaller {
    public void fly(Smaller s) { /* 날개를 달아준다. */ }
}

class 빠냐 extends Niniz implements Smaller {
    public void fly(Smaller s) { /* 날개를 달아준다. */ }
}

대성공이었다! 역시 무지 내 새끼 똑똑하네^_^ 이렇게 해서 3명에게 예쁜 날개를 달아주었고, 6명의 친구들은 에버랜드에서 아침부터 신나게 놀고 야간 퍼레이드까지 보고 집에 돌아와서 푹 잠이 들었다고 한다.

'Java' 카테고리의 다른 글

내부 클래스  (0) 2022.05.19
디폴트 메서드  (0) 2022.05.15
인터페이스 선언, 상속, 구현  (0) 2022.05.13
추상 클래스 작성하기  (0) 2022.05.11
추상 클래스, 추상 메서드  (0) 2022.05.05