JAVA/JAVA

인터페이스

호두밥 2021. 11. 30. 01:37

인터페이스란?

완벽한 추상 클래스 : 모든 메소드가 추상 메소드 (abstact method)로 이루어져 있는 클래스

interface Animal {
  public void animalSound(); // interface method (does not have a body)
  public void run(); // interface method (does not have a body)
}

* 추상 메소드 : 정의만 되어있는 메소드로 실제 기능을 구현되어 있지 않은 것을 의미.

인터페이스의 역할

다형성을 구현할 수 있다.

인터페이스를 사용하면 메소드를 호출할 때, 인터페이스의 구조만 알면 되고, 객체 각각의 내부 구현에 대해서는 알 필요가 없어진다.

* 다형성이란 동일한 요청을 받았을 때 객체의 타입에 따라 다르게 응답할 수 있는 능력을 의미한다.

아래 그림과 같은 동물 인터페이스가 있다.

동물 인터페이스를 사용하여 애완동물 클래스를 정의하였다. 그리고 애완동물의 "울다" 메소드를 동물 인터페이스의 "울다" 메소드를 호출하도록 정의하였다.

public class 애완동물 {

    private String 이름;
    private 동물  종류;

    public 애완동물(String 이름, 동물 종류) {
        this.이름 = 이름;
        this.종류 = 종류;
    }

    public String 울다(){
       return this.종류.울다();
    }
}

아래와 같이 애완동물 객체를 선언한 뒤 "울다" 메소드를 호출하면 "야옹"이 출력된다.

public class controller {

    public static void main(String[] args) {

        애완동물 꾼이 = new 애완동물( "꾼이", new 고양이() );

        System.out.println("꾼이가 울면? = " + 꾼이.울다());

    }
}

꾼이가 울면? = 야옹

애완동물 객체를 선언하는 시점에 종류가 "고양이"라는 정보를 입력해주었고, 이 정보를 동물 인터페이스가 받아 "고양이" 객체의 "울다" 메소드를 호출해준 것이다.

만약 애완동물의 종류가 고양이가 아니고 강아지라고 하면 애완동물 객체를 선언하는 부분만 "강아지"로 변환해주면 된다.

이렇게 개발 코드를 여러 군데 건드리지 않고 객체만 바꾸면 소스를 재사용 할 수 있도록 하는 특성을 다형성이라고 한다.

애완동물 꾼이 = new 애완동물( "꾼이", new 강아지() );

인터페이스의 특징과 구성요소

  1. 특징 :

    1. 상수와 메소드만 있다.
      인터페이스는 객체를 생성할 수 없기 때문에 생성자를 가질 수 없다.
    2. 기본적으로 public
      인터페이스의 모든 메소드와 상수는 기본적으로 public 으로 선언된다. 메소드 앞에 접근제한자를 붙이지 않는다면 컴파일 과정에서 public이 자동으로 붙게 된다.
      • 일반적인 클래스는 접근제한자를 붙이지 않는다면 컴파일 과정에서 default 접근제한자가 붙는다.
  2. 구성요소

    1. 상수 필드 (static final field)
      인터페이스에 고정된 값으로 외부에서 변경할 수 없다.

    2. 추상 메소드 (abstract method)
      정의만 있는 메소드로 구현부는 인터페이스를 상속받은 객체가 가지고 있다.

    3. 디폴트 메소드 (default method)
      자바 8부터 추가된 기능으로, 인터페이스가 정의와 구현부를 모두 갖고 있다. 그러나 인터페이스를 상속받은 객체에서만 메소드 사용이 가능하다. 구현 클래스에서 오버라이드로 구현하지 않아도 메소드를 사용할 수 있다.
      인터페이스를 구현한 클래스에서 재정의(@Override)할 수 있다.

      public interface 동물 {
      public String 울다();
      public default String 먹다(){ 
          return "사료"; 
      } 
      } 
      public class 고양이 implements 동물 {
      @Override public String 울다() { 
          return "야옹"; 
      } 
      } 
      public static void main(String[] args) {
      System.out.println("꾼이의 먹이는 = " + 꾼이.먹다()); 
      }

      꾼이의 먹이는 = 사료

    4. 정적 메소드 (static method)
      자바 8부터 추가된 기능으로, 인터페이스가 정의와 구현부를 모두 갖고 있다. 디폴트 메소드와는 다르게 인터페이스에서 바로 메소드를 사용할 수 있다.
      인터페이스를 구현한 클래스에서 재정의(@Override)할 수 없다.

      public interface 동물 { 
          public String 울다(); 
          public static String 자다(){ 
              return "쿨쿨"; 
          }
         } 
      System.out.println("자다 = " + 동물.자다());

      자다 = 쿨쿨

public interface 인터페이스 명{
    // 상수
    타입 상수명 = 값;    
    // 추상 메소드
    타입 메소드명(매개변수, ...);    
    // 디폴트 메소드
    default 타입 메소드명(매개변수, ...){
    // 구현부
    }    
    // 정적 메소드
    static 타입 메소드명(매개변수, ...){
        // 구현부
    }
}

인터페이스와 구현객체

  1. implements
    인터페이스를 구현한 클래스는 implements 로 어떤 인터페이스를 구현한 것인지를 나타내주어야 한다.
  2. @Override
    인터페이스를 구현한 클래스는 인터페이스의 추상 메소드를 구현해야 한다.
public class 고양이 implements 동물 {

    @Override
    public String 울다() {
        return "야옹";
    }
}
  1. 구현 객체 대입
    인터페이스로 변수를 선언하고 인터페이스를 구현한 클래스 객체를 대입해서 사용한다.

    동물 삼색이 = new 고양이();

    인터페이스로 객체를 대입한 경우에는 객체의 고유 메소드는 사용할 수 없다. 예를 들어서 아래처럼 고양이 클래스만 가지고 있는 "놀다"라는 메소드는 동물 객체로 선언된 삼색이에서 호출이 불가능하다.

    public class 고양이 implements 동물 {
      @Override
      public String 울다() {
          return "야옹";
      }
      public String 놀다() { return "사냥하다"; };
    }

    이런 경우에는 고양이 클래스로 삼색이를 캐스팅(형변환)하면 고양이 클래스의 메소드를 호출할 수 있다.

    ((고양이) 삼색이).놀다();
  2. 익명 구현 객체
    구현 클래스 파일을 생성하지 않고 소스에서 바로 클래스를 선언하여 사용할 수 있는 방법이다. (자바 8 람다식)

    동물 햄스터 = new 동물(){ 
        @Override public String 울다() {
            return "찍!"; 
        } 
     }; 
     애완동물 햄릿 = new 애완동물("햄릿", 햄스터); 
     System.out.println("햄릿이 울면? = " + 햄릿.울다());

햄릿이 울면? = 찍!

  1. 다중 인터페이스 구현 클래스
    하나의 클래스가 여러 인터페이스를 구현할 수 있다. 구현 대상인 인터페이스의 모든 추상 메소드를 구현해야 한다. 하나라도 빠지면 추상 클래스로 선언해야 한다.
public class 클래스 implements 인터페이스A, 인터페이스B {
    //인터페이스A의 추상메소드 구현
    //인터페이스B의 추상메소드 구현
}

인터페이스 상속

  • 인터페이스는 다중 상속이 가능하다.
  • 하위 인터페이스를 구현하는 클래스는 하위 인터페이스가 상속받은 추상 메소드들을 모두 구현해야 한다.
  • 하위 인터페이스의 구현 클래스는 상위 인터페이스로 타입변환이 가능하다.

인터페이스의 기본 메소드 (Default Method), 자바 8

인터페이스의 static 메소드, 자바 8

인터페이스의 private 메소드, 자바 9

  • 자바 9 부터 사용가능한 기능으로 인터페이스 내부에 private 메소드를 선언/구현할 수 있게 되었다. 그리고 default 메소드에서 private 메소드를 호출하여 사용할 수 있다.
  • 참고 링크 : https://www.baeldung.com/java-interface-private-methods

참조

'JAVA > JAVA' 카테고리의 다른 글

정적 팩토리 메소드와 빌더 패턴  (0) 2023.06.24
I/O  (0) 2022.02.06
Optional  (0) 2021.11.07
스트림 Stream  (0) 2021.11.07
Comparator와 Comparable  (0) 2021.10.29