[기본 개념] 2 | (7.3) 인터페이스, 디폴트 메서드

728x90

[기본 개념] 2 | (7.3) 인터페이스, 디폴트 메서드

1 인터페이스란?

2 인터페이스의 작성

3 인터페이스의 상속

4 인터페이스의 구현

5 인터페이스를 이용한 다중상속

6 인터페이스를 이용한 다형성

7 인터페이스의 장점

8> 인터페이스의 이해

9> 디폴트 메서드

8. 인터페이스의 이해

인터페이스의 규칙이나 활용이 아닌, 본질적인 측면에 대해 살펴보자.

 

- 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provoider)이 있다.

- 메서드를 사용(호출)하는 쪽 (User)에서는 사용하려는 메서드(Provoid)의 선언부만 알면 된다.

 

예제/InterfaceTest.java

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.methodA(new B());
    }
}

class A {           // User
    public void methodA(B b) {
        b. methodB();
    }
}

class B {           // Provider
    public void methodB() {
        System.out.println("methodB()");
    }
}
실행결과

methodB()

 

클래스 A(User)는 클래스 B(Provider)의 인스턴스를 생성하고 호출하는 직접적인 관계에 있다.

 

 이 경우 클래스 A를 작성하려면 클래스 B가 이미 작성되어 있어야 하고, 클래스 B의 methodB( )의 선언부가 변경되면, 클래스 A도 변경되어야 한다.

 

 이처럼 직접적인 관계의 두 클래스는 한쪽(Providrer)이 변경되면 다른 한쪽(User)도 변경되어야 한다는 단점이 있다.

 

 그러나 직접 호출하지 않고 인터페이스를 매개체로 해서 접근하도록 하면 클래스 B의 변경사항이  클래스 A에 전혀 영향을 받지 않는다.

 

 두 클래스를 간접적인 관계로 변경하려면 인터페이스를 이용하여 클래스의 B(Provider)의 선언과 구현을 분리해야 한다.

 

먼저 다음과 같이 클래스 B에 정의된 메서드를 추상메서드로 정의하는 인터페이스 I를 정의한다.

 

        interface I {

            public abstract void methodB( ) ;

        }

 

그다음에는 클래스 B가 인터페이스 I를 구현하도록 한다.

 

        class B implements I {

            public void methodB( ) {

                System.out.println("methodB in class") ;

            }

        }

 

이제 클래스 A는 클래스 B 대신 인터페이스 I를 사용해서 작성할 수 있다

 


    class A {

        public void methodA(B b) {
            b. methodB();
        }
    }

---->
    class A {
        public void methodA(I i) {
            i. methodB();
        }
    }

 

 이제 클래스 A를 작성하는데 클래스 B가 사용되지 않는다. 클래스 A는 인터페이스 I하고 직접적인 관계에 있기 때문에 실제로 사용되는 클래스 이름을 몰라도 되고, 실제로 구현된 클래스가 존재하지 않아도 된다.

9. 디폴트 메서드

 원래 인터페이스에 추상메서드만 선언할 수 있는데, JDK1.8에서부터 디폴트메서드와 static메서드도 추가되었다.

 

디폴트메서드

 인터페이스가 변경되지 않으면 좋겠지만 언젠가는 변경이 필요할 것이다. 이때 디폴트메서드를 사용할 수 있는데, 추상메서드의 기본적인 구현을 제공하는 메서드로, 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.

 

디폴트메서드는 앞에 키워드 'defaul'를 붙이며, 추상메서드와 달리 몸통 { }이 있어야 한다.

 

 인터페이스에 추상메서드를 추가하는 대신, 디폴트메서드를 추가하면 조상클래스에 새로운 메서드를 추가한 것과 같은 효과를 얻는다.

 

대신 새로 추가된 디폴트메서드가 기존의 메서드와 이름이 중복되는 경우 해결하는 규칙은 다음과 같다.

 

1 여러 인터페이스의 디폴트메서드 간의 충돌

- 인터페이스를 구현한 클래스에서 디폴트메서드를 오버라이딩해야 한다.

2 디폴트메서드와 조상클래스의 메서드 간의 충돌

- 조상 클래스의 메서드가 상속되고, 디폴트메서드는 무시된다.

 

 

 

 

출처 | Java의 정석 (남궁 성)

 

 

728x90