본문 바로가기
Programming/JAVA

[Effective Java] 인터페이스 활용하기

by 코딩의성지 2023. 2. 9.

자바를 처음 접한 사람이라면 누구나 인터페이스를 왜 쓰는지에 대한 의문을 가진적이 있을 것이다.

추상클래스만으로도 충분히 사용이 가능할 것 같고, 오히려 인터페이스를 쓰면 프로그램의 복잡도만 올라갈 것 같은데라는 생각을 아마도 하지 않았을까 생각한다.

 

허나 인터페이스는 객체지향의 세계를 구현하기 위한 가장 중요한 요소중 하나이다.

 

오늘은 이 인터페이스에 대해 정리를 좀 해두겠다. 

 

먼저 확장과 구현에 대한 개념을 정리해두자.

클래스의 확장과 인터페이스의 구현의 가장 큰 차이는 클래스의 확장은 하나만 가능한 반면 인터페이스의 구현은 여러개가 가능하다.

public class Sub extends Super implements Serializable, Cloneable {
	...
}

그리고 인터페이스는 여러개의 인터페이스를 확장하는 것도 가능하다.

public interface Sub extends Serializable, Cloneable {
	...
}

 

내가 정말 자주 이용하는 중고거래 어플리케이션인  D 마켓의 초기 개발자로 빙의해 보겠다.

(이해를 돕기위한 아주 허접한 예시이니 참고만 부탁드린다.)

D마켓은 초기에 중고거래에 대한 서비스 기획만 있었다고 생각해보자. 그래서 개발자인 나는 아래와 같은 설계를 진행했다.

public class DMarket extends SecondHand {
	...
}

이렇게 개발된 서비스는 날이갈수록 잘되었고 다른 서비스에 대한 수요가 발생하기 시작했다. 그러더니 갑자기 부동산 거래기능과 알바 구인 기능도 넣자는 기획이 생겼다. 당황할법도 하지만 나는 아래와 같이 인터페이스를 이용해서 문제를 해결했다.

public class DMarket implements SecondHandAvailable, RealEstateAvailable, Hireable {
	// 중고거래 기능 구현
    // 부동산 거래 기능 구현
    // 알바 고용 기능 구현
}

이렇게 설명을 드리면 어느정도 인터페이스를 이용했을 때 어떤 이점이 있을지가 느껴지실거라 생각한다.

 

그리고 자바 8 이후 부터는 default 키워드를 통해 공통적인 메서드 기능도 정의하는게 가능하다는것도 알아두자.

public interface SecondHandAvailable {
	// 추상메서드
    void getItemInfo();
    
    //default 메서드
    default void pay() {
    	...
    }
}

 

 

default 메서드를 잘 이용하면 OCP 원칙을 잘 지켜서 설계가 가능해진다

 

하지만 만약에 RealEstateAvailable 인터페이스와 Hireable 인터페이스에도 pay() 메서드가 default 메서드로 구현이 되어 있다면 DMarket이 컴파일 될때 어떤 메서드를 사용해야될지 몰라 에러를 발생시킨다. 이문제를 다이아몬드 문제라 부르는데 이러한 상황을 조심하도록 하자.

 

또한 Object의 메서드(equals, toString)들은 default 메서드로 제공하면 안되는 것도 기억해두자.

 

그리고 실무에서는 이 인터페이스와 추상클래스를 효율적으로 사용하는데. 이 방식을 추상 골격 구현 (Skeletal implementation) 이라 부른다. 추상 골격 구현은 아래 3단계를 거쳐서 구현한다.

 

1. interface로 뼈대 만들기

2. 추상클래스로 필요한 구현 모두 하기

3. 서브클래스로 마무리하기

반응형

댓글