본문 바로가기

프로그래밍/JAVA

[ JAVA ] 인터페이스(interface)

1. 인터페이스란?

▶ 인터페이스는 일종의 추상클래스이다.
▶ 추상메서드와 상수만을 멤버로 가질 수 있다.
▶ 밑그림만 그려져 있는 '기본 설계도'라고 할 수 있다. 

2. 인터페이스의 작성

▶ 인터페이스를 작성하는 것은 클래스를 작성하는 것과 같으며, 키워드로 interface를 사용한다.
▶ 접근제어자로 public 또는 default를 사용할 수 있다.
▶ 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
▶ 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
▶ 생략된 제어자는 컴파일 시에 컴파일러가 자동적으로 추가해준다.
▶ JDK1.8이하에서 인터페이스의 모든 메서드는 추상메서드이어야 함.
    JDK1.8부터 인터페이스에 static메서드와 디폴트 메서드(default method)의 추가를 허용하는 방향으로 변경됨.

 

3. 인터페이스의 상속

▶ 인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와는 달리 다중상속, 즉 여러 개의 인터페이스로부터 상속을 받는 것이 가능하다.
▶ 인터페이스는 클래스와 달리 Object클래스와 같은 최고 조상이 없다.

 

4. 인터페이스의 구현

 ▶ 인터페이스는 그 자체로는 인스턴스를 생성할 수 없다. 따라서 인터페이스에 정의된 추상메서드를 구현해 줄 클래스를 작성해야 한다.
▶ 인터페이스의 구현은 일반 클래스에서 implements 키워드를 사용하여 구현한다.
▶ 구현하는 인터페이스의 메서드 중 일부만 구현한다면, abstract를 붙여서 추상클래스로 선언해야 한다.
▶ 상속과 구현을 동시에 할 수 있다.

※ 인터페이스의 이름에는 주로 '~을 할 수 있는'의 의미인 'able' 로 끝나는 것들이 많은데, 그 이유는 어떠한 기능 또는 행위를 하는데 필요한 메서드를 제공한다는 의미를 강조하기 위해서이다. 하지만 모든 인터페이스의 이름이 반드시 'able'로 끝나야 하는 것은 아니다.

예시)

❗️오버라이딩 할 때는 조상의 메서드보다 넓은 범위의 접근 제어자를 지정해야 한다.

  > Movable 인터페이스에 move 메서드는 사실 'public abstract'가 생략된 것이기 때문에 실제로 'public abstract void move(int x, int y)' 이다. 그러므로 이를 구현하는 Fighter 클래스에서는 move 메서드의 접근 제어자를 반드시 public으로 해야 한다.

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

▶ 인터페이스는 static 상수만 정의할 수 있으므로 조상클래스의 멤버변수와 충돌하는 경우는 거의 없고, 충돌된다 하더라도 클래스 이름을 붙여서 구분이 가능하다.
▶ 추상메서드는 구현내용이 전혀 없으므로 조상클래스의 메서드와 선언부가 일치하는 경우에는 조상 클래스 쪽의 메서드를 상속받으면 된다.
▶ 두 개의 클래스로부터 상속받아야 할 경우
    두 조상클래스 중에서 비중이 높은 쪽을 상속받고 다른 한쪽은 클래스 내부에 멤버로 포함시키는 방식으로 처리하거나
    어느 한쪽의 필요한 부분을 뽑아서 인터페이스로 만든 다음 구현하도록 한다. 

예시) TVCR클래스에 두 클래스(Tv클래스, VCR클래스)를 상속받는 방법

  ▶️ Tv클래스VCR클래스를 작성한다.

 

  ▶️ VCR클래스에 정의된 메서드와 일치하는 추상메서드를 갖는 IVCR인터페이스를 작성한다.

  

▶️ IVCR인터페이스를 구현하고 Tv클래스로부터 상속받는 TVCR클래스를 작성한다.

      이때 VCR클래스 타입의 참조변수를 멤버변수로 선언하여 IVCR인터페이스의 추상메서드를 구현하는데 사용한다.

 

※ IVCR인터페이스를 구현하기 위해서는 새로 메서드를 작성해야하는 부담이 있지만
   이처럼 VCR클래스의 인스턴스를 사용하면 손쉽게 다중상속을 구현할 수 있고, VCR클래스의 내용이 변경되어도
   변경된 내용이 TVCR클래스에도 자동적으로 반영되는 효과를 얻을 수 있다.

※ 인터페이스를 새로 작성하지 않고도 VCR클래스를 TVCR클래스에 포함시키는 것만으로도 충분하지만,

   인터페이스를 이용하면 다형적 특성을 이용할 수 있다는 장점이 있다.

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

▶ 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 형변환도 가능하다.
▶ 인터페이스는 메서드의 매개변수의 타입으로 사용될 수 있다.
인터페이스 타입의 매개변수가 갖는 의미 : 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다.
▶ 메서드의 리턴타입으로 인터페이스의 타입을 지정하는 것이 가능하다.
리턴타입 인터페이스 : 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.

 

 > Fightable타입의 참조변수로는 인터페이스 Fightable에 정의된 멤버들만 호출이 가능하다.

7. 인터페이스의 장점

1️⃣ 개발시간을 단축시킬 수 있다.

  > 인터페이스가 작성되면, 이를 사용해서 프로그램을 작성하는 것이 가능하다.
      메서드를 호출하는 쪽에서는 메서드의 내용에 관계없이 선언부만 알면 되기 때문이다.

2️⃣ 표준화가 가능하다.

  > 프로젝트에 사용되는 기본 틀을 인터페이스로 작성한 다음, 개발자들에게 인터페이스를 구현하여 프로그램을 작성하도록 함으로써 
     보다 일관되고 정형화된 프로그램의 개발이 가능하다. 

3️⃣ 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.

  > 서로 상속관계에 있지도 않고, 같은 조상클래스를 가지고 있지 않은 서로 아무런 관계도 없는 클래스들에게 
     하나의 인터페이스를 공통적으로 구현하도록 함으로써 관계를 맺어 줄 수 있다.

4️⃣ 독립적인 프로그래밍이 가능하다.

  > 인터페이스를 이용하면 클래스의 선언과 구현을 분리시킬 수 있기 때문에 실제구현에 독립적인 프로그램을 작성하는 것이 가능하다.

8. 인터페이스의 이해

▶ 클래스를 사용하는 쪽(User)과 클래스를 제공하는 쪽(Provider)이 있다.
▶ 메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다. (내용은 몰라도 됨)

예시) 직접적인 관계의 두 클래스 (클래스 A, 클래스 B)

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

▶️ 한 쪽(Provider)이 변경되면 다른 한 쪽(User)도 변경되어야 한다는 단점이 있다.

예시) 간접적인 관계의 두 클래스 (클래스 A, 클래스 B)

▶️ 클래스A가 클래스B의 메서드를 호출하지만, 클래스A는 인터페이스I하고만 직접적인 관계에 있기 때문에 클래스 B의 변경에 영향을 받지 않는다.

▶️ 클래스A는 인터페이스를 통해 실제로 사용하는 클래스의 이름을 몰라도 되고, 실제로 구현된 클래스가 존재하지 않아도 문제되지 않는다.

▶️ 클래스A autoPlay 메서드의 매개변수는 인터페이스I를 구현한 클래스의 인스턴스를 동적으로 제공받아야 한다.

9. 디폴트 메서드와 static메서드

▶ 원래는 인터페이스에 추상 메서드만 선언할 수 있는데, JDK1.8부터 디폴트 메서드와 static메서드도 추가할 수 있게 되었다.
▶ 디폴트 메서드(default method)는 추상 메서드의 기본적인 구현을 제공하는 메서드이다.
▶ 디폴트 메서드는 추상 메서드가 아니기 때문에 디폴트 메서드가 인터페이스에 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
▶ 디폴트 메서드는 앞에 키워드 default를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통 {}이 있어야 한다.
▶ 디폴트 메서드의 접근 제어자는 public이며, 생략가능하다.

 

🔷 새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우 해결 방법

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

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

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

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