hoon's bLog

Java interface implements 자바 인터페이스 구현 본문

IT/Java

Java interface implements 자바 인터페이스 구현

개발한기발자 2021. 1. 6. 14:26
반응형

안녕하세요?

이번 시간에는 인터페이스에 대해서 포스팅을 하도록 하겠습니다.

Spring & Spring Boot 가 대세가 되어버린 요즘 시점에서 인터페이스는 주로 많이 쓰이고,

중요한 개념으로 자리 잡고 있는데요?!

한번 이 인터페이스에 대해서 알아보도록 하겠습니다!

우선 인터페이스에 대한 사전적 정의에 대해서 알아보도록 하겠습니다.

인터페이스란?

하나의 시스템을 구성하는 2개의 구성 요소(하드웨어, 소프트웨어), 또는 2개의 시스템이
상호작용할 수 있도록 접속되는 경계(boundary), 이 경계에서 상호 접속
하기 위한
하드웨어, 소프트웨어, 조건, 규약 등을 포괄적으로 가리키는 말

출처 : 위키백과

 

그렇다면 자바에서는 어떤 의미로 사용될까요?

일종의 추상클래스! 개발자 사이의 코드 규약을 정합니다.
여러 구현체에서 공통적인 부분을 추상화합니다.(다형성)
오직 추상메서드와 상수만을 멤버로 가질 수 있습니다!

 

inerface 기본 문법

interface 인터페이스명{
      public static final 타입 상수이름 = 값;
      public abstract 메서드이름(매개변수목록);
}
//모든 멤버변수는 public static final 이어야 하며 이를 생략가능!
//모든 메서드는 public abstract 이어야 하며, 역시 생략 가능!

 

자바 인터페이스는 기본적으로 추상메서드의 모음입니다.

추상메서드는 아래와 같이 구현부가 없는 메서드를 말합니다.

public interface Walkable {
        void walk();
}

 

현부가 없으므로 인터페이스를 만든다면 반드시 구현하는 클래스를 만들어야 하며,

인터페이스를 구현하기로 한 클래스는 반드시 인터페이스에 명시되어 있는 추상메서드들을 모두 구현해야 합니다.

만약 이를 구현하지 않으면 컴파일 에러가 발생합니다.

public class Dog implements Walkable { //Walkable interface를 구현한 클래스 Dog
        // ...
        @Override
        public void walk() {
                // ...
        }
}

 

인터페이스는 구현과 상속을 모두 할 수 있습니다.

인터페이스를 사용하는 구체 클래스는 해당 인터페이스를 구현해야 합니다.

인터페이스 사이에는 상속을 할 수 있고 인터페이스를 사용하면 다중 상속이 가능합니다.

인터페이스 사이에서도, 구체 클래스에서도 여러 인터페이스를 구현 및 상속할 수 있습니다.

public interface Walkable {
        void walk();
}

public interface Flyable {
        void fly();
}

public interface Moveable extends Walkable, Flyable {
        //...
}

public class Bat implements Moveable {
        @Override
        public void walk() {
                // ...
        }
        
        @Override
        public void fly() {
                // ...
        }
}

 

인터페이스를 만들면서 접근제어자를 생략했는데,

인터페이스는 클래스와 달리 기본 접근제어자는 public 입니다.(접근자는 추후에 다뤄보도록 하겠습니다!)

인터페이스에 필드 변수를 선언하면 public static final로 선언해야 하며, 생략하면 기본으로 설정되어 있습니다.

메서드를 private로 설정하면 실제 구현체를 인터페이스 내에 구현해야 합니다.

(물론 이를 밖에서 사용할 수 없으므로 직접적으로 사용하는 곳은 크게 많지 않을 것 같습니다...ㅎㅎㅎ)

default 접근 제어자

Java 8 버전 이상부터는 인터페이스에서 default 접근 제어자를 사용할 수 있다고 합니다!

이는 인터페이스 내에서 직접 메서드를 구현한다는 의미의 접근 제어자이고.

이를 구현한 구현클래스는 오버라이딩없이 default 메서드를 사용할 수 있으며, 오버라이딩 역시 할 수 있습니다.

이로 인해 다중 상속일 때 고려해야 할 사항이 많아지는 등 복잡했죠.

하지만 이를 만든 주된 이유는 라이브러리 업데이트 때문입니다.

인터페이스는 라이브러리나 프레임워크에서 매우 자주 사용되는데.

라이브러리를 업데이트할 때 인터페이스에 추가된 기능이 있다면 이를 구현한 클래스 역시 추가해주어야 합니다.

하지만 이 라이브러리를 사용하는 사용자가 해당 인터페이스를 구현한 클래스가 있다면,

이를 구현하지 않아 컴파일 에러가 발생하게 되죠.

이러한 심각한 불편함을 해소하기 위해 default라는 키워드를 만들었다고 합니다.

인터페이스를 사용하는 이유

인터페이스를 사용하는 주된 이유는 다형성을 위해서라고 생각합니다.(다른 좋은 정보와 생각 환영입니다!!)

다형성은 상속받은 클래스 또는 인터페이스의 메서드를 재정의하여 서로 다른 행동을 만들 수 있습니다.

상속을 통해 상위 클래스의 타입으로 통일한 후 하위 클래스들을 하나의 타입으로 관리할 수 있습니다.

이를 사용해서 변경에 유연한 코드를 만들 수 있습니다.

인터페이스는 구현체가 없습니다.

이를 구현한 클래스에서 모든 구현체를 만들어야 합니다.(default 접근 제어자 제외)

예를 들어 한 인터페이스를 구현한 A, B 클래스가 있다고 하자. 현재는 A 클래스를 사용하고 있지만,

인터페이스를 잘 설계했다면 다른 기존 코드의 변경이 거의 없이 B 클래스로 쉽게 변경할 수 있습니다.

자바의 JDBC가 이렇게 구현되어 있으며, Spring에서도 대부분 이러한 인터페이스 장점을 잘 활용하고 있습니다.

인터페이스와 상속 차이

다형성을 활용하기 위해서는 기본적으로 자바를 기준으로 클래스 상속과 인터페이스 구현으로 나뉘죠?

이를 선택하는 것은 전적으로 개발자의 몫입니다만, 판단을 도와주는 기준은 존재합니다.

상속에 대해서는 일반적으로 다음과 같이 추천합니다.

상속보다는 위임을 사용하기

다형성을 위한 것이라면 클래스 상속보다는 인터페이스를 구현하기.

 

위를 보면 대부분 상속을 추천하지 않습니다. 그만큼 비용이 큰 작업이기 때문이죠.

변하지 않는 구조에서 상속을 사용하면 중복 코드를 제거하고 깔끔하게 코드를 작성할 수 있지만,

변화가 발생하는 순간 상속 구조는 깨지기 쉽습니다.

예를 들어 상속 관계에서 부모 클래스에 기능이 추가되었는데,

자식 클래스 중 하나에서 이를 사용할 수 없도록 해야 한다면 상속 구조가 깨질 수 있습니다.

따라서 상속은 기본적으로 Is-A 관계가 확실하고, 설계 이후에 변화가 없는 곳에서 사용해야 합니다.

하지만 현실은 설계 이후에도 기능 변화가 비일비재하기 때문에 대부분 인터페이스를 사용합니다.

위 상속 문제에서 일부 자식 클래스에서는 필요하고, 일부에서는 필요하지 않은 기능이 있다고 했습니다.

이러한 기능들은 실제로 실무에서도 설계 이후에 생기는 경우가 빈번합니다.

그래서, 인터페이스를 잘 활용할 줄 안다면 보다 효율적으로, 쉽게 구성할 수 있습니다.

참 사용은 하면서도 막상 말로 하면 잘 안 되는 문법들이 참 많은 것 같습니다.

특히 뒤로 갈수록 더 그런 것 같기도 하고요...

내가 무언갈 확실히 안다는 것은 내가 말로 풀어낼 줄 알고,

누군가에게 알려줄 수 있는 게 진정한 알아감이 아닐까 싶습니다 ㅎㅎㅎ

다음엔 제어자에 대해서 포스팅해보도록 하겠습니다.

오늘도 하찮은 글 읽어주시느라 감사합니다!

 

출처 : 자바의 정석 3rd Edition 내용 정리

728x90
반응형