본문 바로가기
안드로이드/자바

자바의 인터페이스란?

by 나이아카 2021. 8. 10.

 자바에서 인터페이스라는 친구는 대학교 2학년 자바 수업때 처음 들었습니다. 그때는 인터페이스는 불필요한 코드라는 생각도 어느정도 했었는데, 어느정도 시간이 지나고 자바와 코틀린을 사용해서 프로그래밍을 하다보니 인터페이스라는 친구가 계속해서 사용되더라구요. 그래서 시간이 날 때 한 번 정리를 해봐야겠다는 생각입니다.

 먼저 인터페이스에는 세 가지 규칙이 존재합니다.

 첫 번째로는 인터페이스 내부 메소드는 전부 public abstract로 선언되어야 한다는 점입니다. 물론 이는 생략하고 사용해도 자동으로 변경되어 문제가 발생하지는 않습니다.

 두 번째로는 인터페이스 내부 변수들은 모두 public static final로 선언되어야 한다는 점으로, int number = 1;과 같이 사용해도 첫 번째처럼 자동으로 코드를 변경시켜 줍니다.

 마지막으로는 터페이스 내부 메소드는 실제 코드를 구현하지 않는 것인데, 이 부분에 대해서는 자바 8로 넘어오면서 default 키워드가 생겨서 실제로 맞지 않는 규칙이 되었습니다. default 키워드란 아래 코드에서 볼 수 있는 것처럼, 인터페이스 내부에서 코드의 기능을 미리 구현해두는 것을 의미합니다. 이로 인해 코틀린에서는 자연스럽게 인터페이스에서 코드를 구현할 수 있습니다.

 인터페이스는 실제로 기능의 구현이 아닌, 어떠한 기능을 사용하겠다는 명시에 가까운 코드 방식인데 그러한 방식과 다르게 default 키워드가 등장하게 된 이유는, 하위 호완성 때문이라고 합니다. 이는 기존에 사용중인 인터페이스에 추가적인 메소드를 삽입하고 싶은데, 그 추상 메소드를 삽입하게 되면 그 인터페이스를 사용하는 모든 코드에 그 기능을 명시해주어야 하는 문제가 존재합니다. 그러나 이를 default 키워드를 사용하게 되면, 추가 되더라도 그 메소드를 사용하지 않으면 코드를 수정할 필요가 없어집니다.

 

public interface InterfaceName {
    int count;

    public Object methodname1(Object data);
    public abstract Object methodname2(Object data);
    
    //default로 선언함으로 메소드를 구현할 수 있다.
    default Object getData(Object data){
        return data;
    }
}

 자바의 인터페이스는 이런식으로 생성할 수 있습니다.

 인터페이스는 기본적으로 정해진 메소드와 리턴타입을 통해 어떤 기능인지에 대해서 미리 정의해놓은 후, 실제로 사용하기 위해 만들어두는 것이 주 목적입니다. 

 예를 들어, 두 사람이 새로운 클래스를 만들어낼 때 세부 내용은 다르지만, 기본 개념은 동일한 코드를 작성해야할 때 두 사람이 동일한 메소드명이나 리턴 타입을 강제할 수 있습니다.

public interface Code {
    public abstract Object add(Object data);
    
    public abstract Object Update(Object data);
    
    public abstract boolean Delete(Object data);
}

 

 만약 코더 1과 코더 2가 서로 데이터를 추가하는 기능을 만든다고 가정했을 때, 코더 1은 insert 메소드를, 코더 2는 add 메소드를 만들게 되면 서로 코드가 통일되지 않아 추후 코드의 통합이나 관리 측면에서 커뮤니케이션이 잘 되지 않을 수 있습니다. 그러나 이러한 인터페이스가 존재한다면 서로 다른 두 사람이 코드를 작성하게 되더라도, 추가는 항상 add 메소드를 사용할 것이라는 점을 확인할 수 있습니다. 또한 혼자 코딩을 하더라도 명확하게 코딩 스타일을 정의하더라도 가끔씩 어색하거나 달라지는 부분이 생기는 것을 방지하는데 효과적입니다.

 인터페이스에 정의해둔 코드들은 상속을 통해 작업할 때, 모두 필수적으로 재정의되어야 합니다.

 더욱이 이러한 인터페이스를 사용하는 경우, 내부 알고리즘 로직이 변경되어야 할 때, 프로젝트에서 인터페이스를 사용하는 부분은 두고, 그 안의 메소드만 변경해주면 자연스럽게 교체가 가능하다는 것도 하나의 이점으로 볼 수 있습니다.

 또한, 인터페이스는 다중상속을 지원하기 때문에 여러가지 인터페이스를 적용할 수 있습니다. 특정한 사람이 사람이라는 특성 뿐 아니라 세부적인 여러 특성을 가질 수 있는 것처럼, 클래스 역시 여러 인터페이스를 통해 정해진 메소드들을 호출하는 경우가 있습니다. 기존의 클래스는 다중상속이 되지 않아 여러번 상속을 통해 받아야 하지만 인터페이스는 다중 상속이 가능해 한 클래스에 다 implements할 수 있습니다.

public CodeStyle implements Code {
    
    ArrayList<Object> list = new ArrayList();

    public boolean add(Object data) {
        //리스트 추가 코드 작성
    }
    
    public boolean Update(Object data) {
        //리스트 변경 코드 작성
    }
    
    public boolean Delete(Object data) {
        //리스트 제거 코드 작성
    }
}

 위의 Code 인터페이스를 상속받으면 이런식으로 코드를 작성하게 됩니다. 세부 내용의 경우 리턴 타입에 맞게끔만 작성해준다면 이 코드는 인터페이스를 제작한 사람에게 굉장히 익숙한 코드가 될 것입니다. 이렇듯 인터페이스는 여러명 혹은 스스로가 작업을 할 때, 가이드 문서와 같은 역할을 해줍니다. 또한 코드를 강제함으로서 필요한 기능을 항상 동일한 메소드명으로 동작시켜 코드의 가독성을 높여줄 수 있습니다.

 


 이러한 인터페이스는 코딩을 하다보면 생각보다 여러군데에서 자주 사용되는 것을 확인할 수 있습니다. 대충 알고 있으니 왜 사용하는지에 대한 궁금증이 없었을 때는 그저 인터페이스를 사용해야 하는 라이브러리에서 사용하는 것만 생각하고 썼었는데, 어느정도 호기심이 생기고 난 후에는 어떤 방식으로 사용하게 되는지를 찾아보게 되어 역시 아는게 많아야 실력이 는다는 것을 깨닫게 되었습니다.

댓글