[Java] 인터페이스 ③

kiteB·2022년 1월 8일
0

Java

목록 보기
19/35
post-thumbnail

[ 인터페이스 사용 ]

인터페이스로 구현 객체를 사용하려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다.

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

예제

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

RemoteControl rc;
rc = new Television();
rc = new Audio();

개발 코드에서 인터페이스는 클래스의 필드, 생성자 또는 메소드의 매개 변수, 생성자 또는 메소드의 로컬 변수로 선언될 수 있다.

public class MyClass {

    //필드
    RemoteControl rc = new Television();
    
    //생성자
    MyClass(RemoteControl rc) {
        this.rc = rc;
    }
    
    //메소드
    void methodA() {
        //로컬 변수
        RemoteControl rc = new Audio();
    }
    
    void methodB(RemoteControl rc) { ... }
}

1. 추상 메소드 사용

구현 객체가 인터페이스 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 호출할 수 있게 된다. 개발 코드에서 RemoteControl의 변수 rcturnOn() 또는 turnOff() 메소드를 호출하면 구현 객체의 turnOn()turnOff() 메소드가 자동 실행된다.

RemoteControl rc = new Television();
rc.turnOn();	//Television의 turnOn() 실행
rc.turnOff();	//Television의 turnOff() 실행

예제 | 인터페이스 사용

public class RemoteControlExample {
    public static void main(String[] args) {
    
        RemoteControl rc = null;	//인터페이스 변수 선언
    
    	rc = new Television();	//Television 객체를 인터페이스 타입에 대입
        rc.turnOn();	//인터페이스의 turnOn() 호출
        rc.turnOff();	//인터페이스의 turnOff() 호출
        
        rc = new Audio();	//Audio 객체를 인터페이스 타입에 대입
        rc.turnOn();	//인터페이스의 turnOn() 호출
        rc.turnOff();	//인터페이스의 turnOff() 호출
    }
}

실행결과

TV를 켭니다.
TV를 끕니다.
Audio를 켭니다.
Audio를 끕니다.

2. 디폴트 메소드 사용

  • 디폴트 메소드는 인터페이스에 선언되지만, 인터페이스에서 바로 사용할 수 없다.
  • 디폴트 메소드는 추상 메소드가 아닌 인스턴스 메소드이므로 구현 객체가 있어야 사용할 수 있다.

RemoteControl 인터페이스는 setMute()라는 디폴트 메소드를 가지고 있지만, 다음과 같이 사용할 수 없다.

RemoteControl.setMute(true);

setMute() 메소드를 호출하려면 RemoteControl구현 객체가 필요한데, 다음과 같이 Television 객체를 인터페이스 변수에 대입하고 나서 setMute()를 호출할 수 있다. 비록 setMute()Television에 선언되지는 않았지만 Television 객체가 없다면 setMute()도 호출할 수 없다.

RemoteControl rc = new Television();
rc.setMute(true);

디폴트 메소드는 인터페이스의 모든 구현 객체가 가지고 있는 기본 메소드라고 생각하면 된다.

그러나 어떤 구현 객체는 디폴트 메소드의 내용이 맞지 않아 수정이 필요할 수도 있다. 구현 클래스를 작성할 때 디폴트 메소드를 재정의(오버라이딩)해서 자신에게 맞게 수정하면 디폴트 메소드가 호출될 때 자신을 재정의한 메소드가 호출된다.

예제

  • Audio (구현 클래스)
public class Audio implements RemoteControl {

    //필드
    private int volume;
    private boolean mute;
    
    //turnOn() 추상 메소드의 실체 메소드
    public void turnOn() {
        System.out.println("Audio를 켭니다.");
    }
    //turnOff() 추상 메소드의 실체 메소드
    public void turnOff() {
        System.out.println("Audio를 끕니다.");
    }
    //setVolume() 추상 메소드의 실체 메소드
 	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("현재 Audio 볼륨: " + this.volume);
    }
    
    //디폴트 메소드 재정의
    @Override
    public void setMute(boolean mute) {
        this.mute = mute;
        
        if (mute) {
            System.out.println("Audio 무음 처리합니다.");
        } else {
            System.out.println("Audio 무음 해제합니다.");
        }
    }
}
  • RemoteControlExample (디폴트 메소드 사용)
public class RemoteControlExample {
    public static void main(String[] args) {
        RemoteControl rc = null;
        
        rc = new Television();
        rc.turnOn();
        rc.setMute(true);
        
        rc = new Audio();
        rc.turnOn();
        rc.setMute(true);
    }
}

실행 결과

TV를 켭니다.
무음 처리합니다.
Audio를 켭니다.
Audio 무음 처리합니다. 

Audio 클래스에서 디폴트 메소드인 setMute를 오버라이딩 했으므로 무음 처리합니다.가 아닌 Audio 무음 처리합니다.가 호출된다.


3. 정적 메소드 사용

인터페이스의 정적 메소드는 인터페이스로 바로 호출이 가능하다.

public class RemoteControlExample {
    public static void main(String[] args) {
        RemoteControl.changeBattery();
    }
}

[ 참고자료 ]

이것이 자바다 책

profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글