자바 기초 (12). 인터페이스
추상 클래스 추상 메서드에 이은 , 자바 인터페이스에 대해 알아보도록 하자
0. 들어가기전에
인터페이스란 객체의 사용 방법을 정의한 타입
인터페이스를 통해 다양한 객체를 동일한 사용 방법으로 이용할 수 있다.
인터페이스를 이용해서 다형성을 구현할 수 있다.
__인터페이스__란 :
- 개발 코드는 인터페이스를 통해서 객체와 서로 통신한다. (개발코드는 인터페이스만 오로지 보고 개발하면 된다.)
- 인터페이스의 메서드 호출하면 객체의 메서드가 호출된다.
- 개발 코드를 수정하지 않으면서 객체 교환이 가능하다.
1. 인터페이스 선언
- *.java 형태 소스 파일로 작성 및 컴파일러 통해 ~.class 형태로 컴파일이 된다.
- 클래스와 물리적 파일 형태는 같으나 소스 작성 내용이 조금 다르다.
[public] interface [인터페이스네임] {...}
- 인터페이스는 객체로 생성할 수 없으므로 생성자를 가질 수 없다. ( 추상클래스와 틀리다 )
- 인터페이스의 변수필드는 상수(불변의 값)으로 설정된다. (자동으로 static final 과 같이 사용된다. 그래서 반드시 값을 초기에 주어야 한다. )
interface 인터페이스네임 {
// 상수
타입 상수이름 = 값;
// 추상 메서드, 추상메서드 답게 구현 블럭이 없다.
타입 메서드이름(매개변수,...);
}
이전에 배운 상수 필드를 다시 한번 알아보자
1-1 상수필드 (constant field) 선언
- 인터페이스에서는 데이터를 저장할 인스턴스 혹은 정적 필드 선언 불가
- 상수 필드만 선언 가능
- 상수 이름은 대문자로 작성하고 서로 다른 단어로 구성되 있는경우 언더바를 통해 연결한다.
public interface RemoteController{
// static final은 생략되어도 가능
public int MAX_VOLUME = 10;
public static final int MIN_VOLUME = 0;
}
1-2 추상 메서드 선언
- 인터페이스 통해 호출된 메서드는 최종적으로 객체(재정의된 메서드)에서 실행된다.
- 인터페이스의 메서드는 실행 블럭 필요 없는 추상 메서드로 선언 (호출 방법만 기술)
- 어차피 추상메서드만 가능하므로 [public abstract] 생략가능하다
[public abstract] 리턴타입 메서드이름(매개변수, ...);
추상 메서드 선언
public interface RemoteController{
// static final은 생략되어도 가능
public int MAX_VOLUME = 10;
public static final int MIN_VOLUME = 0;
void turnOn();
void turnOff();
void setVolume(int volume);
}
2. 인터페이스 구현
인터페이스 뒷편에서 객체를 만들기 위해서는 구현클래스를 구현해야 한다.
구현(implement) 클래스
- 인터페이스 정의된 추상 메서드를 재정의해서 실행 내용을 가지고 있는 클래스
- 클래스 선언부에 implements 키워드를 추가하고 인터페이스 이름 명시
public class 구현클래스이름 implements 인터페이스이름 {
// 인터페이스에 선언된 추상 메서드의 실제 메서드 선언
}
실제 구현하기 위해선 추상메서드를 실제 클래스에선 모두 재정의 overrinde해줘야 한다.
- 인터페이스 변수 선언하고 구현 객체를 대입
인터페이스 변수; 변수 = 구현체 인터페이스 변수 = 구현객체;
java코드 ```java // 위에 만든 RemoteController 인터페이스 // Television은 실제 구현 클래스 RemoteController tvRc = new Television(); tvRc.turnOn(); tvRc.turnOff();
RemoteController audioRc = new Audio(); audioRc.turnOn(); audioRc.turnOff();
Television Class
```java
public class Television implements RemoteController{
private int volume;
@Override
public void turnOn(){
System.out.println("티비를 켠다");
}
@Override
public void turnOff(){
System.out.println("티비를 끈다");
}
@Override
public void setVolume(int volume){
if(volume > RemoteController.MAX_VOLUME){
this.volume = RemoteController.MAX_VOLUME;
}else if (volume < RemoteController.MIN_VOLUME){
this.volume = RemoteController.MIN_VOLUME;
}else {
this.volume = volume;
}
System.out.println("현재 볼륨은" : this.volume);
}
}
다중 인터페이스 구현 클래스 객체는 다수 인터페이스 타입으로도 사용이 가능하다.
public class 구현클래스이름 implements 인터페이스A, 인터페이스B{
// 인터페이스 A에 선언된 추상 메서드의 실제 메서드 선언
// 인터페이스 B에 선언된 추상 메서드의 실제 머서드 선언
}
3. 인터페이스 사용
인터페이스는 필드, 매개 변수, 로컬 변수 타입으로 선언이 가능하다.
public class MyClass{
// 필드
RemoteController rc = new Television();
// 생성자
MyClass(RemoteController rc){
this.rc = rc;
}
// 메서드
void moethod(){
//로컬 변수
RemoteController rc = new Audio();
rc.turnOn();
}
void methodB(RemoteController rc){
rc.turnOn();
}
}
그런데 위의 글들을 보고도 하나 풀리지 않는 의문점이 있다. 왜 Spring MVC 패턴에서 service와 serviceImpl은 1대1 관계로 위와 같이 사용하지 않을까 ( 위 포스팅에선 인터페이스에도 충분한 장점이 있으나, 위처럼 1대1 관계가 되면 이러한 이점을 전혀 가젹지 못한다. ) ?? 남들 다 그렇게 짜니까?? 뭐 그럴수도 있지만 이유는 따로 있다.
그 이유는 아래글을 확인해 보면 될것 같다. [MVC 구조에서 service와 serviceImpl]