[Java] 인터페이스
인터페이스
인터페이스의 역할
인터페이스는 사전적인 의미로 두 장치를 연결하는 접속기를 말한다. 여기서 두 장치를 서로 다른 객체로 본다면, 인터페이스는 이 두객체를 연결하는 역할을 한다.
- 이미지 출처 : https://hyuntaekhong.github.io/assets/images/java/java-basic20/interface02.png
인터페이스 선언
인터페이스 선언은 class 키워드 대신 interface 키워드를 사용한다. 접근 제한자로는 클래스와 마찬가지로 같은 패키지 내에서만 사용 가능한 default,
패키지와 상관없이 사용하는 public을 붙일 수 있다.
interface 인터페이스명 { ... } //default 접근 제한
public interface 인터페이스명 { ... } //pubilc 접근 제한
package ch08.sec02;
public interface RemoteControl {
//public 추상 메소드
public void turnOn();
}
구현 클래스 선언
implements 키워드는 해당 클래스가 인터페이스를 통해 사용할 수 있다는 표시이며, 인터페이스의 추상 메소드를 재정의한 메소드가 있다는 뜻이다.
public class B implements 인터페이스명 { ... }
앞에서 선언한 RemoteControl의 추상 메소드인 turnOn()을 다음과 같이 재정의한다.
package ch08.sec02;
public class Television implements RemoteControl {
@Override
public void turnOn(){
System.out.println("TV를 켭니다."); //인터페이스에 선언된 turnOn() 추상 메소드 재정의
}
}
package ch08.sec02;
public class Audio implements RemoteControl{
@Override
public void turnOn(){
System.out.println("Audio를 켭니다.");
}
}
package ch08.sec02;
public class RemoteControlExample {
public static void main(String[] args) {
RemoteControl rc;
rc = new Television();
rc.turnOn();
rc = new Audio();
rc.turnOn();
}
}
상수 필드
인터페이스는 public static final 특성을 갖는 불변의 상수 필드를 멤버로 가질 수 있다.
[ public static final ] 타입 상수명 = 값;
package ch08.sec03;
public interface RemoteControl {
int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
}
package ch08.sec03;
public class RemoteControlExample {
public static void main(String[] args) {
System.out.println("리모컨 최대 볼륨: "+RemoteControl.MAX_VOLUME);
System.out.println("리모컨 최저 볼륨: "+RemoteControl.MIN_VOLUME);
}
}
추상 메소드
인터페이스는 구현 클래스가 재정의해야 하는 public 추상 메소드를 멤버로 가질 수 있다.
추상 메소드는 리턴 타입, 메소드명, 매개변수만 기술되고 중괄호 {}를 붙이지 않는 메소드를 말한다.
public abstract를 생략하더라도 컴파일 과정에서 자동으로 붙게 된다.
[public abstract ] 리턴타입 메소드명(매개변수, ...);
package ch08.sec04;
public interface RemoteControl {
//상수 필드
int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
//추상 메소드 - 메소드 선언부만 작성
void turnOn();
void turnOff();
void setVolume(int volume);
}
package ch08.sec04;
public class Television implements RemoteControl {
//필드
private int volume;
//turnOn() 추상 메소드 오버라이딩
@Override
public void turnOn(){
System.out.println("TV를 켭니다.");
}
//turnOff() 추상 메소드 오버라이딩
@Override
public void turnOff(){
System.out.println("TV를 끕니다.");
}
//setVolume() 추상 메소드 오버라이딩
@Override
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.volume);
}
}
package ch08.sec04;
public class Audio implements RemoteControl{
//필드
private int volume;
//turnOn() 추상 메소드 오버라이딩
@Override
public void turnOn(){
System.out.println("Audio를 켭니다.");
}
//turnOff() 추상 메소드 오버라이딩
@Override
public void turnOff(){
System.out.println("Audio를 끕니다.");
}
//setVolume() 추상 메소드 오버라이딩
@Override
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 볼륨: "+volume);
}
}
구현 객체가 대입되면 인터페이스 변수로 추상 메소드를 호출할 수 있게 된다. 이때 어떤 구현 객체가 대입되었는지에 따라 실행 내용이 달라진다.
Television이 대입되었다면 Television의 재정의된 메소드가, Audio가 대입되었다면 Audio의 재정의된 메소드가 실행된다.
package ch08.sec04;
public class RemoteControlExample {
public static void main(String[] args) {
//인터페이스 변수 선언
RemoteControl rc;
//Television 객체를 생성하고 인터페이스 변수에 대입
rc = new Television();
rc.turnOn();
rc.setVolume(5);
rc.turnOff();
//Audio 객체를 생성하고 인터페이스 변수에 대입
rc = new Audio();
rc.turnOn();
rc.setVolume(5);
rc.turnOff();
}
}
다중 인터페이스 구현
구현 객체는 여러 개의 인터페이스를 implements 할 수 있다. 구현 클래스는 다음과 같이 인터페이스 A와 인터페이스 B를 implements 뒤에 쉼표로 구분해서 작성해,
모든 인터페이스가 가진 추상 메소드를 재정의해야 한다.
public class 구현클래스명 implements 인터페이스A, 인터페이스B {
//모든 추상 메소드 재정의
}
인터페이스A 변수 = new 구현클래스명(...);
인터페이스B 변수 = new 구현클래스명(...);
package ch08.sec08;
public interface RemoteControl {
//추상 메소드
void turnOn();
void turnOff();
}
package ch08.sec08;
public interface Searchable {
//추상 메소드
void search(String url);
}
package ch08.sec08;
public class SmartTelevision implements RemoteControl, Searchable{
//turnOn() 추상 메소드 오버라이딩
@Override
public void turnOn(){
System.out.println("TV를 켭니다.");
}
//turnOff() 추상 메소드 오버라이딩
@Override
public void turnOff(){
System.out.println("TV를 끕니다.");
}
//search() 추상 메소드 오버라이딩
@Override
public void search(String url){
System.out.println(url+"을 검색합니다.");
}
}
package ch08.sec08;
public class MultiInterfaceImplExample {
public static void main(String[] args) {
//RemoteControl 인터페이스 변수 선언 및 구현 객체 대입
RemoteControl rc = new SmartTelevision();
//RemoteControl 인터페이스에 선언된 추상 메소드만 호출 가능
rc.turnOn();
rc.turnOff();
//Searchable 인터페이스 변수 선언 및 구현 객체 대입
Searchable searchable = new SmartTelevision();
//Searchable 인터페이스에 선언된 추상 메소드만 호출 가능
searchable.search("https://www.youtube.com");
}
}
인터페이스 상속
인터페이스도 다른 인터페이스를 상속할 수 있으며, 클래스와는 달리 다중 상속을 허용한다.
public interface 자식인터페이스 extends 부모인터페이스1, 부모인터페이스2 {...}
package ch08.sec09;
public interface InterfaceA {
//추상 메소드
void methodA();
}
package ch08.sec09;
public interface InterfaceB {
//추상 메소드
void methodB();
}
package ch08.sec09;
public interface InterfaceC extends InterfaceA, InterfaceB{
//추상 메소드
void methodC();
}
package ch08.sec09;
public class InterfaceCImpl implements InterfaceC{
public void methodA(){
System.out.println("InterfaceCImpl-mehtodA() 실행");
}
public void methodB(){
System.out.println("InterfaceCImpl-mehtodB() 실행");
}
public void methodC(){
System.out.println("InterfaceCImpl-mehtodC() 실행");
}
}
package ch08.sec09;
public class ExtendsExample {
public static void main(String[] args) {
InterfaceCImpl impl = new InterfaceCImpl();
InterfaceA ia = impl;
ia.methodA();
//ia.methodB(); --> X
System.out.println();
InterfaceB ib = impl;
//ib.methodA(); --> X
ib.methodB();
System.out.println();
InterfaceC ic = impl;
ic.methodA();
ic.methodB();
ic.methodC();
}
}
- 출처: 이것이 자바다
댓글남기기