인터페이스란 ?
- 기능 사용을 위한 규약
- 객체의 사용 방법을 정의한 타입
- 다양한 객체를 동일한 방법으로 이용할 수 있게 해줌
- 개발 코드에서 인터페이스의 메소드를 호출하면 이제 인터페이스가 객체의 메소드를 호출시킴
- 개발 코드를 수정하지 않고 객체를 변경할 수 있게 하여 개발 코드 측면에서 실행 내용과 리턴 값을 다양화할 수 있다.
인터페이스 선언
1. 특징
- 클래스와 규칙이 동일함 (대문자로 시작)
- 상수 필드와 추상 메소드만을 멤버로 가진다. ( 객체를 생성할 수 없기 때문에 생성자는 가질 수 없음)
- 인터페이스는 객체 사용 방법만 정의한 것이므로 인스턴스나 정적 필드를 선언할 수 없다. (상수 필드는 고정된 값이므로 선언이 가능)
- 최종 실행은 객체에서 실행되므로 인터페이스에서 메소드의 실행 코드를 입력할 필요가 없다.
- 따라서 인터페이스에서는 추상 메소드를 선언해준다.
2. 형태
public interface RemoteControl { // 인터페이스 생성
// 상수
public static final int MAX_VALUE = 10; // public static final은 생략 가능, 자동으로 붙게됨
// 추상 메소드
public abstract void turnOn(); // public abstract 생략 가능, 자동으로 붙게됨
}
인터페이스 구현
- 위에서 다룬 예제와 같이 RemoteControl 은 인터페이스고 이제 Television과 Audio가 구현 클래스가 된다.
- 구현 클래스 : 구현 객체를 생성하는 클래스로, 인터페이스에서 정의한 추상메소드를 구현 클래스에서 오버라이딩한 실체 메소드를 가지고 있어야 한다.
- 구현 객체 : 구현 클래스로 만들어진 객체를 말한다.
구현 클래스
- 특징 : 보통 클래스와 동일하지만 인터페이 타입으로 사용이 가능함을 알리기 위해 implements 키워드 사용한다.
- 특징 : 인터페이스에 선언된 추상 메소드의 실체 메소드를 선언해야함
- 형태 :
public class 구현클래스명 implements 인터페이스명 {
인터페이스에서 선언된 추상 메소드의 실체 메소드 선언
}
인터페이스 구현 예제
<인터페이스>
public interface RemoteControl { // 인터페이스 생성
// 상수
public static final int MAX_VALUE = 10; // public static final은 생략 가능, 자동으로 붙게됨
public static final int MIN_VALUE = 0;
// 추상 메소드 -> 기본적으로 전부 public 접근 제한자를 가짐
public abstract void turnOn(); // public abstract 생략 가능, 자동으로 붙게됨
public abstract void turnOff();
public abstract void setVolume(int volume);
}
<구현 클래스 1>
class Television implements RemoteControl { // 인터페이스 사용이 가능하게 됨
// 필드
private int volume;
// RemoteControl 인터페이스에 있는 추상 메소드 세개에 대한 실체 메소드를 모두 작성해주어야함
// 인터페이스의 추상 메소드가 모두 public 접근 제한을 가지므로 더 낮은 접근 제한으로 실체 메소드 작성 불가
// 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_VALUE) { // 인터페이스 상수를 이용해서 volume 필드의 값을 제한
this.volume = RemoteControl.MAX_VALUE; // 최대값을 넘으면 값을 최대값으로 지정(최대값을 못넘도록 해줌)
} else if(volume < RemoteControl.MIN_VALUE) {
this.volume = RemoteControl.MIN_VALUE;
} else {
this.volume = volume;
}
System.out.println("현재 TV 볼륨 : " + this.volume);
}
}
<구현 클래스 2>
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_VALUE) {
this.volume = RemoteControl.MAX_VALUE;
} else if(volume < RemoteControl.MIN_VALUE) {
this.volume = RemoteControl.MIN_VALUE;
} else {
this.volume = volume;
}
System.out.println("현재 Audio 볼륨 : " + this.volume);
}
}
<인터페이스 객체에 구현 객체 대입>
- Television tv = new Television(); <- 이 방법은 인터페이스를 사용하여 객체를 만든 것이 아님
- 인터페이스 변수를 먼저 선언하고 구현 객체를 대입해주어야함
- 인터페이스 변수는 참조 타입이므로 구현 객체를 대입할 때 구현 객체의 번지가 저장됨
public class RemoteControlExample {
public static void main(String[] args) {
RemoteControl rc;
rc = new Television();
rc = new Audio();
}
}
다중 인터페이스 구현 클래스
- 여러 인터페이스로부터 구현 클래스를 작성하기 위해선 모든 인터페이스에 선언된 추상 메소드의 실체 메소드를 선언
- 형태
public class 구현클래스명 implements 인터페이스1, 인터페이스2 {
인터페이스 A에 선언된 추상 메소드의 실체 메소드 선언
인터페이스 B에 선언된 추상 메소드의 실체 메소드 선언
}
다중 인터페이스 구현 예제
<인터페이스>
interface Searchable {
// 추상 메소드
void search(String Url);
}
<다중 인터페이스 구현 클래스>
class SmartTelevision implements RemoteControl, Searchable {
// 필드
private int volume;
private String name;
// 생성자
public SmartTelevision(String name) {
this.name = name;
}
// 실체 메소드
@Override
public void search(String url) {
System.out.println(url + "을 검색합니다.");
}
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
@Override
public void setVolume(int volume) {
if(volume > RemoteControl.MAX_VALUE) {
this.volume = RemoteControl.MAX_VALUE;
} else if(volume < RemoteControl.MIN_VALUE) {
this.volume = RemoteControl.MIN_VALUE;
} else {
this.volume = volume;
}
System.out.println("현재 TV 볼륨 : " + this.volume);
}
}
<인터페이스 변수에 구현 객체 대입>
public class SmartTelevisionExample {
public static void main(String[] args) {
SmartTelevision stv = new SmartTelevision("SAMSUNG smart TV"); // 구현 객체 생성
// 자동 형변환 (RemoteControl <- SmartTelevision)
// RemoteControl 기능만 사용 가능
RemoteControl rc = stv; // 인터페이스 변수에 객체 대입
rc.turnOn();
//자동 형변환 (Searchable <- SmartTelevision)
// Searchable 기능만 사용 가능
Searchable sc = stv;
sc.search("www.google.com");
// sc.turnOn(); 사용 못함
}
}
<출력 결과>
TV를 켭니다.
www.google.com을 검색합니다.
인터페이스 사용 과정 구조화
인터페이스 사용 과정
- 인터페이스는 개발 코드(MyClass)와 구현 객체(Television, Audio) 사이에서 접점 역할을 담당
- 개발 코드에서 인터페이스(RemoteControl)의 추상메소드(turnOn(), turnOff()) 호출
- 호출된 인터페이스는 구현 객체의 재정의 메소드인 실체 메소드(turnOn(), turnOff())를 호출함
인터페이스 사용
- 구현 객체가 인터페이스 변수에 대입되므로 이제 인터페이스로 구현 객체를 사용할 수 있다.
- 인터페이스가 쓰이는 예시
1. 필드로 사용
// 객체 코드 myClass에서 인터페이스를 필드로 선언
RemoteControl rc = new Television();
// 객체 코드 myClass 에서 선언된 필드 사용
MyClass myclass = new MyClass(); // 객체 생성
myClass.rc.turnOn(); // rc 변수에는 Television 객체의 번지가 저장되어있으므로
myClass.rc.setVolume(5); // television의 메소드가 실행됨
2. 생성자의 매개변수 타입으로 사용 ( 메소드의 매개변수로도 사용 가능)
// 객체 코드 MyClass의 생성자에서 인터페이스를 매개변수로 사용
MyClass(RemoteControl rc) { // 매개변수에 인터페이스 타입이 들어감
this.rc = rc;
rc.turnOn(); // 인터페이스의 메소드 호출
rc.setVolume(5);
}
// 객체를 생성할 때 구현 객체를 받으면 구현 클래스의 실체 메소드가 실행됨
MyClass myClass = new MyClass(new Audio()); // Audio의 메소드들이 실행됨
3. 메소드 내부에서 로컬 변수로 사용 (생성자의 로컬 변수로도 가능)
// 메소드 안에서 로컬 변수로 인터페이스 타입이 사용됨
void methodA() {
RemoteControl rc = new Audio();
rc.turnOn(); // Audio의 turnOn()이 실행됨
rc.setVolume(5); // Audio의 setVolume(5)이 실행됨
}
4. 메소드의 매개변수 타입으로 사용
// 메소드의 매개변수 타입으로 사용
void methodB(RemoteControl rc) {
rc.turnOn();
rc.setVolume(5);
}
// 실행 클래스에서 methodB() 호출
MyClass myClass = new MyClass();
myClass.methodB(new Television());
인터페이스 사용 예제
<개발 코드>
public class MyClass {
// 인터페이스의 사용 예시 4가지
// 1. 필드로 사용
RemoteControl rc = new Television();
// 기본 생성자
MyClass() {
}
// 2. 생성자로 사용
MyClass(RemoteControl rc) { // 매개변수에 인터페이스 타입이 들어감
this.rc = rc;
rc.turnOn(); // 인터페이스의 메소드 호출
rc.setVolume(5);
}
// 3. 메소드 내에서 로컬 변수로 사용
void methodA() {
RemoteControl rc = new Audio();
rc.turnOn(); // Audio의 turnOn()이 실행됨
rc.setVolume(5); // Audio의 setVolume(5)이 실행됨
}
// 4. 메소드의 매개변수 타입으로 사용
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());
}
}
<출력 결과>
1)----------------
TV를 켭니다.
현재 TV 볼륨 : 5
2)----------------
Audio를 켭니다.
현재 Audio 볼륨 : 5
3)----------------
Audio를 켭니다.
현재 Audio 볼륨 : 5
4)----------------
TV를 켭니다.
현재 TV 볼륨 : 5
'👨🏫Study > JAVA' 카테고리의 다른 글
[JAVA] 09 - 1 중첩 클래스와 중첩 인터페이스 소개 (0) | 2022.03.21 |
---|---|
[JAVA] 08 - 2 타입 변환과 다형성 (0) | 2022.03.21 |
[JAVA] 07 - 3 추상 클래스 (0) | 2022.03.21 |
[JAVA] 07 - 2 타입 변환과 다형성 (0) | 2022.03.21 |
[JAVA] 07 - 1 상속 (0) | 2021.08.11 |
댓글