이것이 자바다 의 Chapter08 을 참고하여 정리한 포스트입니다.

이전글
인터페이스 이론정리 - 1

Chapter 08. 인터페이스 - (2)

3. 인터페이스 구현

객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 실체 메소드를 가지고 있어야 한다.
이러한 객체를 구현(implement) 객체라고 하고, 구현 객체를 생성하는 클래스를 구현 클래스라고 한다.

3.1 구현 클래스

1
2
3
public class 구현클래스명 implements 인터페이스명 {
    // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
}

구현 클래스에서 인터페이스의 추상 메소드들의 실체 메소드 작성 시 주의할 점
인터패이스의 모든 메소드들은 기본적으로 public 접근 제한을 갖기 때문에 public 보다 낮은 접근 제한으로 작성은 불가하다. public 를 생략하면 컴파일 에러가 발생한다.


아래의 예제는 RemoteControl.java 에 3개의 추상 메소드가 있기 때문에 Television과 Audio 실체 메소드를 작성해야 한다.
RemoteControl.java 예제 확인하기
  • ex) Television.java 구현 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    public class Televsion implements RemoteControl {
      //필드
      private int volume;
    
      //1. turnOn() 추상 메소드의 실체 메소드
      public void turnOn() {
          System.out.println("TV를 켭니다. ");
      }
    
      //2. turnOff() 추상 메소드의 실체 메소드
      public void turnOff() {
          System.out.println("TV를 끕니다. ");
      }
    
      //3. setVolume() 추상 메소드의 실체 메소드
      public void setVolume(int volume) {
          // 인터페이스 상수를 이용해서 volume 필드의 값을 제한
          if(volume > RemoteControl.MAX_VOLUME) {
              this.volume = RemoteControl.MAX_VOLUME;
          } else if(volume < RemoteControl.MIN_VOLUME) {
              this.volume = RemoteControl.MIN_VOLUME;
          } else {
              this.volume = volume;
          }
          System.out.println("현재 TV 볼륨 : "+this.volune);
      }
    }
    
  • ex) Audio.java 구현 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    public class Audio implements RemoteControl {
      //필드
      private int volume;
    
      //1. turnOn() 추상 메소드의 실체 메소드
      public void turnOn() {
          System.out.println("Audio를 켭니다. ");
      }
    
      //2. turnOff() 추상 메소드의 실체 메소드
      public void turnOff() {
          System.out.println("Audio를 끕니다. ");
      }
    
      //3. setVolume() 추상 메소드의 실체 메소드
      public void setVolume(int volume) {
          // 인터페이스 상수를 이용해서 volume 필드의 값을 제한
          if(volume > RemoteControl.MAX_VOLUME) {
              this.volume = RemoteControl.MAX_VOLUME;
          } else if(volume < RemoteControl.MIN_VOLUME) {
              this.volume = RemoteControl.MIN_VOLUME;
          } else {
              this.volume = volume;
          }
          System.out.println("현재 Audio 볼륨 : "+this.volune);
      }
    }
    

인터페이스에 선언된 추상 메소드에 대응하는 실체 메소드를 구현 클래스가 작성하지 않을 경우
실체 메소드를 작성하지 않을 경우 구현 클래스는 자동적으로 추상 클래스가 되기 때문에 클래스 선언부에 abstract 키워드를 추가해야 한다.

1
2
3
4
5
public abstract class Television implements RemoteControl {
    // 아래의 클래스는 setVolume() 실체 메소드가 없다. (일부만 구현)
    public void turnOn() {...}
    public void turnOff() {...}
}

인터페이스 구현 객체 사용

이클립스에서 [ Source → Override/Implement Method… → 추상 메소드 체크 → Ok ]
자동 생성된 실체 메소드는 @Override 가 붙으며, 이는 인터페이스의 추상 메소드에 대한 정확한 실체 메소드인지 컴파일러가 체크하도록 지시하는 어노테이션이다.
구현 클래스가 작성되면 new 연산자로 객체를 생성할 수 있다. (어떤 타입의 변수에 대입?)

구현 객체를 인터페이스 변수에 대입해서 사용
인터페이스로 구현 객체를 사용해려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다.
인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 경우 구현 객체의 번지를 저장한다.

인터페이스 변수;
변수 = 구현객체;
or
인터페이스 변수 = 구현객체;

ex) RemoteControl 인터페이스로 구현 객체인 Television 과 Audio 를 사용하려면 RemoteControl 타입 변수 rc를 선언하고 구현 객체를 대입해야 한다.

  • RemoteControlExample.java 인터페이스 변수에 구현 객체 대입
    1
    2
    3
    4
    5
    6
    7
    
    public class RemoteControlExample {
      public static void main(String[] args) {
          RemoteControl rc;
          rc = new Television();
          rc = new Audio();
      }
    }
    

3.2 익명 구현 객체

구현 클래스를 만들어 사용하는 것이 일반적이지만 자바에서 이벤트를 처리하거나, 임시 작업 스레드를 만들기 위해 익명 구현 객체를 활용한다.
자바 8에서 지원하는 람다식은 인터페이스의 익명 구현 객체를 만든다.

익명 구현 객체 생성, 인터페이스 변수에 대입
하나의 실행문이므로 끝에는 세미콜론(;)을 반드시 붙인다.
1
2
3
인터페이스 변수 = new 인터페이스() {
    // 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
};

new 연산자 뒤에는 클래스 이름이 와야 하지만 이름이 없는 이유
인터페이스() { }
- 인터페이스를 구현해서 중괄호 { } 와 같이 클래스를 선언하라는 뜻,
- 인터페이스에 선언된 모든 추상 메소드들의 실체 메소드를 작성해야 한다. (작성하지 않으면 컴파일 에러)
- 필드와 메소드를 선언할 수 있지만, 익명 객체 안에서만 사용할 수 있고 인터페이스 변수로 접근할 수 없다.

new 연산자 : 선언된 클래스를 객체로 생성

  • ex) RemoteControl의 익명 구현 객체 만들기
    RemoteControlExample.java 익명 구현 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public class RemoteControlExample {
      public static void main(String[] args) {
          RemoteControl = rc = new RemoteControl() {
             public void turnOn() {/*실행문*/}
             public void turnOff() {/*실행문*/}
             public void setVolume(int volume) {/*실행문*/}
          };
      }
    }
    

    모든 객체는 클래스로부터 생성되듯이 익명 구현 객체도 그렇다.
    RemoteControl.java 를 컴파일하면 자바 컴파일러에 의해 클래스 파일이 만들어 진다.
    $ 뒤에는 1 부터 시작하는 생성번호가 붙는다.

    1
    
    RemoteControlExample$1.class
    

3.3 다중 인터페이스 구현 클래스

객체는 다수의 인터페이스 타입으로 사용할 수 있다.

  • 인터페이스 A 와 인터페이스 B가 객체의 메소드를 호출할 수 있으려면 객체는 이 두 인터페이스를 모두 구현해야 한다.
    1
    2
    3
    4
    
    public class 구현 클래스명 implements 인터페이스A, 인터페이스B {
      // 인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
      // 인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
    }
    

다중 인터페이스를 구현하는 경우
구현 클래스는 모든 인터페이스의 추상 메소드에 대해 실체 메소드를 작성해야 한다.
하나라도 없을 시 추상 클래스로 선언해야 한다.

  • ex) 인터넷을 검색할 수 있는 Searchable 인터페이스 : serch() 추상 메소드는 매개값으로 URL을 받는다.
    Searchable.java 인터페이스
    1
    2
    3
    
    public interface Searchable {
      void search(String url);
    }
    
  • ex) smartTelevision 이 인터넷 검색 기능도 제공 (RemoteControl + Searchable 를 모두 구현)
    SmartTelevision.java 다중 인터페이스 구현 클래스
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    public class SmartTelevision implements RemoteControl, Searchable {
      private int volume;
    
      // RemoteControl 의 추상 메소드에 대한 실체 메소드
      public void turnOn() {
          System.out.println("TV를 켭니다.");
      }
      public void turnOff() {
          System.out.println("TV를 끕니다.");
      }
      public void setVolume(int volume) {
          if(volume > RemoteControl.MAX_VOLUME) {
              this.volume = RemoteControl.MAX_VOLUME;
          } else if(volume < RemoteControl.MIN_VOLUME) {
              this.volume = RemoteControl.MIN_VOLUME;
          } else {
              this.volume = volume;
          }
          System.out.println("현재 TV 볼륨 : "+this.volune);
      }
    
      // Searchable 의 추상 메소드에 대한 실체 메소드
      public void search(String url) {
          System.out.println(url + "을 검색합니다. ");
      }
    }
    

🌞 정보 : 공부 기록용 블로그입니다. 오타나 내용 오류가 있을 경우 알려주시면 감사하겠습니다.

댓글남기기