본문 바로가기
프로그래밍언어/Java

08-1 인터페이스

by 스꼬맹이브로 2021. 5. 18.
728x90
반응형
SMALL

자바에서의 인터페이스(interface) = 객체의 사용방법을 정의한 타입(개발 코드와 객체가 서로 통신하는 접점 역할)

→ 인터페이스를 통해 다양한 객체를 동일한 사용 방법으로 이용할 수 있음

 

그렇다면 왜 개발 코드가 직접 객체의 메소드를 호출하지 않고 중간에 인터페이스를 두는 걸까?

→ 개발 코드를 수정하지않고 사용하는 객체를 변경할 수 있도록 하기 위해서!

따라서, 개발 코드 측면에서는 코드 변경없이 실행 내용과 리턴 값을 다양화할 수 있다는 장점을 가진다.

 

 

<인터페이스 선언>

인터페이스는 '~.java' 형태의 소스 파일로 작성되고 컴파일러를 통해 '~.class' 형태로 컴파일되기 때문에 물리적 형태는 클래스와 동일하다. 그러나 소스를 작성할 때 선언하는 방법이 class 대신에 interface를 사용한다는 것이 다르다.

인터페이스 이름 작성 방법은 클래스 이름 작성 방법과 동일하다.

//인터페이스 선언 방법
[public] interface 인터페이스이름 {...}

 

클래스는 필드, 생성자, 메소드를 구성 멤버로 가지는데 비해, 인터페이스는 상수 필드와 추상메소드만을 구성 멤버로 가진다.

그 이유는, 인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없다.

interface 인터페이스이름{
  //상수
  타입 상수이름 = 값;
  
  //추상 메소드
  타입 메소드이름(매개변수, ...);
}

 

<상수 필드 선언>

인터페이스는 객체 사용 방법을 정의한 것이므로 데이터를 저장할 수 있는 인스턴스 또는 정적 필드 선언이 불가하다.

하지만 상수 필드는 선언이 가능한데, 상수는 인터페이스에 고정된 값으로 실행 시에 데이터를 변경할 수 없다.

상수 선언시 public static final로 선언하며, 인터페이스에서는 이를 생략하더라도 컴파일 과정에서 자동으로 생성된다.

 

예시 1) RemoteControl 인터페이스에 MAX_VOLUME과 MIN_VOLUME 선언

public interface RemoteControl {
	public int MAX_VOLUME = 10;
	public int MIN_VOLUME = 0;
}

 

<추상 메소드 선언>

인터페이스를 통해 호출된 메소드는 최종적으로객체에서 실행되기 때문에 인터페이스의 메소드는 실행 블록이 필요 없는 추상 메소드로 선언한다.

인터페이스에 선언된 추상 메소드는 모두 public abstract의 특성을 갖기 때문에 이를 생략하더라도 컴파일 과정에서 자동으로 붙게 된다.

 

예시 2) RemoteControl 인터페이스에 turnOn(), turnOff(), setVolume() 추상메소드 선언

public interface RemoteControl {
	//상수
	public int MAX_VOLUME = 10;
	public int MIN_VOLUME = 0;
    
    //추상 메소드
    public void turnOn();
    public void turnOff();
    public void setVolume(int volume);
}

 

<인터페이스 구현>

개발 코드가 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출한다.

객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 실체 메소드를 가지고 있어야 한다.

이러한 객체를 인터페이스의 구현 객체라고 하고, 구현 객체를 생성하는 클래스를 구현 클래스라고 한다.

▶ 구현 클래스

보통의 클래스와 동일한데, 인터페이스 타입으로 사용할 수 있음을 알려주기 위해 클래스 선언부에 implements 키워드를 추가하고 인터페이스 이름을 명시해야 한다.

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

예시 3) RemoteControl 인터페이스를 사용하여 Television과 Audio라는 구현 클래스 작성

public class Television implements RemoteControl {
	//필드
	private int volume;
	
	//turnOn() 추상 메소드의 실체 메소드
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}	
	//turnOff() 추상 메소드의 실체 메소드
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	}
	//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("현재 TV 볼륨: " + this.volume);
	}
}
public class Audio implements RemoteControl {
	//필드
	private int volume;
	
	//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);
	}
}

여기서 주의할 점은 인터페이스의 모든 메소드는 public 접근 제한을 갖기 때문에 public보다 더 낮은 접근 제한으로 작성할 수 없다. 만약 public을 생략한다면 "Cannot reduce the visibility of the inherited method"라는 컴파일 에러가 발생한다.

 

구현 클래스가 작성되면 new 연산자로 객체를 생성할 수 있다. 하지만 기존 객체 생성방법을 사용하면 인터페이스를 사용하지 않으므로 구현 객체를 사용하려면 다음과 같이 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다.

예시 4) RemoteControl 인터페이스를 사용하여 Television과 Audio 사용

public class RemoteControlExample {
	public static void main(String[] args) {
		RemoteControl rc;
		rc = new Television();
		rc = new Audio();
	}
}

 

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

객체는 다수의 인터페이스 타입으로 사용이 가능하다. 

인터페이스 A와 인터페이스 B가 객체의 메소드를 호출할 수 있으려면 객체는 이 두 인터페이스를 모두 구현해야 된다. 구현 방법은 다음과 같다.

public class 구현클래스이름 implements 인터페이스A, 인터페이스B{
	//인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
    //인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
}

또한 다중 인터페이스를 구현할 경우, 구현 클래스는 모든 인터페이스의 추상 메소드에 대해 실체 메소드를 작성해야 한다.

 

예시 5) Searchable 인터페이스(인터넷 검색이 가능한 인터페이스)와 RemoteControl 인터페이스를 통한 SmartTelevision클래스 생성

//Searchable 인터페이스
public interface Searchable{
	void search(String url);
}
public class SmartTelevision implements RemoteControl, Searchable {
	private int volume;
	
	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.volume);
	}
	
	public void search(String url) {
		System.out.println(url + "을 검색합니다.");
	}
}
//인터페이스 변수에 구현 객체 대입
public class SmartTelevisionExample {
	public static void main(String[] args) {
		SmartTelevision tv = new SmartTelevision();
		
		RemoteControl rc = tv;
		Searchable searchable = tv;
	}
}

 

<인터페이스 사용>

예시 5) MyClass를 생성 후 사용

public class MyClass {
	// 필드
	RemoteControl rc = new Television();

	// 생성자
	MyClass() {
	}

	MyClass(RemoteControl rc) {
		this.rc = rc;
		rc.turnOn();
		rc.setVolume(5);
	}

	// 메소드
	void methodA() {
		RemoteControl rc = new Audio();
		rc.turnOn();
		rc.setVolume(5);
	}

	void methodB(RemoteControl rc) {
		rc.turnOn();
		rc.setVolume(5);
	}
}
public class MyClassExample {
	public static void main(String[] args) {
		System.out.println("1)----------------");
		
		MyClass myClass1 = new MyClass();
		myClass1.rc.turnOn();
		myClass1.rc.setVolume(5);
		
		System.out.println("2)----------------");
		
		MyClass myClass2 = new MyClass(new Audio());
		
		System.out.println("3)----------------");
		
		MyClass myClass3 = new MyClass();
		myClass3.methodA();
		
		System.out.println("4)----------------");
		
		MyClass myClass4 = new MyClass();
		myClass4.methodB(new Television());
	}
}

결과 : 

 

728x90
반응형
LIST

'프로그래밍언어 > Java' 카테고리의 다른 글

09-1 중첩 클래스와 중첩 인터페이스 소개  (0) 2021.06.29
08-2 타입 변환과 다형성  (0) 2021.06.28
07-3 추상 클래스  (0) 2021.04.28
07-2 타입 변환과 다형성  (0) 2021.03.09
07-1 상속  (0) 2021.02.25