목차
<인터페이스란?>
구현 코드가 없는 인터페이스
- 인터페이스(interface)는 클래스 혹은 프로그램이 제공하는 기능을 명시적 선언하는 역할.
- 추상 메서드와 상수로만 이루어짐.
- 구현된 코드가 없어서 당연히 인스턴스를 생성할 수 없다.
이러한 인터페이스는 어떻게 사용되어지는지 간단한 계산기를 만들어보자.
- calc 인터페이스
package interfaceex;
public interface Calc {
double PI = 3.14;
int ERROR = -999999999;
// 멤버변수는 public static final(상수)로 자동 선언됨
int add(int num1, int num2);
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
// 메서드는 public abstract(추상메서드)로 자동 선언됨.
}
- 이 인터페이스는 계산기를 만들기 위해 선언한 코드.
- Calc 인터페이스에는 원주율(PI변수), 오류가 났을 때 사용할 ERROR변수, 그리고 사칙 연산을 수행하는 메서드를 선언했다.
- 모두 구현부가 없는 추상 메서드인데 public abstract 예약어를 쓰지 않아도 컴파일 과정에서 자동으로 추상 메서드로 변환된다.
- 인터페이스에 선언한 변수는 public static final을 쓰지 않아도 모두 컴파일 과정에서 값이 변하지 않는 상수로 자동 변환된다.
클래스에서 인터페이스 구현
선언된 인터페이스를 클래스가 사용하는 것을 '클래스에서 인터페이스를 구현한다(implements)'고 표현한다.
상속은 상위 클래스에 구현한 기능을 하위 클래스에서 확장한다는 의미로 'extends 예약어'를 사용했다.
인터페이스에서는 인터페이스에 선언한 기능을 클래스가 구현한다는 의미로 'implements 예약어'를 쓴다.
- Calc인터페이스를 calculater 클래스에서 구현하는 방법은
package interfaceex;
public abstract class Calculator implements Calc { //추상클래스
@Override
public int add(int num1, int num2) {
return num1 + num2;
}
@Override
public int substract(int num1, int num2) {
return num1 - num2;
}
}
- Calculator 클래스에서 Calc 인터페이스를 구현하므로 Calculator 클래스는 추상 메서드 4개를 포함한다. 추상 메서드를 모두 구현하지 않으면 Calculator은 추상 클래스가 된다. (4개 중 2개만 구현하므로 추상 클래스가 됨)
- 클래스 완성하기
이제 Calculator 추상 클래스를 상속받는 CompleteCalc 클래스를 만든다.
package interfaceex;
public class CompleteCalc extends Calculator{
@Override
public int times(int num1, int num2) {
return num1 * num2;
}
@Override
public int divide(int num1, int num2) {
if(num2 != 0) {
return num1 / num2;
}
return ERROR; //num2가 0일 때 오류
}
public void showInfo() {
System.out.println("Calc 인터페이스를 구현하였습니다.");
} //CompleteCalc에서 추가로 구현한 메서드
}
- 숫자를 0으로 나눌 수 없기 때문에 num2가 0이 아닐 때만 나누기 연산을 진행하도록 구현한다. (0일 경우 ERROR 반환)
- 테스트 클래스
package interfaceex;
public class CalculatorTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 5;
CompleteCalc calc2 = new CompleteCalc();
System.out.println(calc2.add(num1, num2));
System.out.println(calc2.substract(num1, num2));
System.out.println(calc2.times(num1, num2));
System.out.println(calc2.divide(num1, num2));
calc2.showInfo();
}
}
- 10과 5를 사칙연산하고 결과 값을 출력한다.
- 구체적인 클래스인 CompleteCalc클래스만 인스턴스를 생성할 수 있다.
그 이유는 Calculator는 추상, Calc는 인터페이스(추상 메서드만 선언)이기 때문.
<인터페이스 구현과 형 변환>
Calculator 클래스는 인터페이스에서 선언한 추상 메서드 중 일부 메서드만 구현하여 추상 메서드다.
그리고 이를 상속받은 CompleteCalc 클래스는 Calculator 클래스에서 구현하지 않은 나머지 추상 메서드를 모두 구현하고 showInfo()메서드를 추가로 구현함.
인터페이스도 상속 관계처럼 하위 클래스는 상위 클래스 자료형으로 묵시적 형 변환할 수 있다.
'CompleteCalc 클래스'는 상위 클래스인 Calculator형이면서, Clac 인터페이스를 구현하였으므로 Calc형이기도 한다.
따라서 별다른 조치 없이 다음처럼 Calc형으로 선언한 변수에 대입할 수 있다.
Calc calc = new CompleteCalc();
여기서 calc변수가 사용할 수 있는 메서드에서 showInfo()는 사용할 수 없다. Calc형으로 선언한 변수에서 사용할 수 있는 메서드는 Calc 인터페이스에 선언한 메서드 뿐이다.
정리하면,
- 인터페이스를 구현한 클래스가 있을 때 그 클래스는 해당 인터페이스형으로 묵시적 형 변환이 이루어진다.
- 형 변환이 되었을 때 사용할 수 있는 메서드는 해당된 형으로 선언한 메서드 뿐이다.
[Do it! 자바 프로그래밍 입문] 도서로 공부하며 정리한 글입니다.