인터페이스로 구현 객체를 사용하려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다.
인터페이스 변수;
변수 = 구현객체;
인터페이스 변수 = 구현객체;
RemoteControl
인터페이스로 구현 객체인 Television
과 Audio
를 사용하려면 다음과 같이 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) { ... }
}
구현 객체가 인터페이스 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 호출할 수 있게 된다. 개발 코드에서 RemoteControl
의 변수 rc
로 turnOn()
또는 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를 끕니다.
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 무음 처리합니다.
가 호출된다.
인터페이스의 정적 메소드는 인터페이스로 바로 호출이 가능하다.
public class RemoteControlExample {
public static void main(String[] args) {
RemoteControl.changeBattery();
}
}
이것이 자바다 책