Java & Kotlin
[Java 객체지향] 인터페이스
Sue
2022. 2. 1. 14:33
인터페이스
- 모든 메서드의 구현 코드가 없는 추상 자료형
- 모든 메서드가 추상 메서드로 선언된다. (public abstract)
- 모든 변수는 상수로 선언된다. (public static final) - 인터페이스는 구현코드가 없으므로 멤버 변수를 가질 수 없음
- 따로 키워드를 넣어주지 않아도 자동으로 추상 메서드 또는 상수로 컴파일 된다.
- 자바에서 모호성을 피하기 위해 단일 상속만 가능하지만, 인터페이스는 구현 코드가 없기 때문에 여러개를 구현하는데 모호성이 발생하지 않는다.
구현과 상속
- 인터페이스를 다른 클래스에서 구현하는 것은 상속과는 다른 의미이다.
- 상속은 이미 구현된 코드를 재사용하는 것이다.
- 인터페이스는 구현된 코드가 없다.
- 다른 클래스에서 인터페이스에 선언된 메서드를 재정의하여 사용하는 것을 인터페이스를 구현한다고 한다.
- 인터페이스의 일부만 구현하면 추상 클래스, 모든 메서드를 구현하면 인스턴스화 될 수 있는 클래스이다.
예제 코드
클래스 다이어그램
- 점선은 인터페이스의 구현(implements)을 나타냄
Calc.java
package ch11;
public interface Calc {
double PI = 3.14; // public static final
int ERROR = -999999999;
int add(int num1, int num2); // public abstract
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
}
Calculator.java
package ch11;
public abstract class Calculator implements Calc{ // interface의 일부 메서드만 구현
@Override
public int add(int num1, int num2) {
return num1 + num2;
}
@Override
public int substract(int num1, int num2) {
return num1 - num2;
}
}
CompleteCalc.java
- 모든 메서드를 구현하여 CompleteCalc 클래스는 인스턴스화 될 수 있다.
package ch11;
public class CompleteCalc extends Calculator { // interface의 나머지 메서드 모두 구현
@Override
public int times(int num1, int num2) {
return num1 * num2;
}
@Override
public int divide(int num1, int num2) {
if (num2 == 0) {
return ERROR;
}
else {
return num1/num2;
}
}
public void showInfo() {
System.out.println("모두 구현했습니다.");
}
}
CalculatorTest.java
- 인터페이스를 구현한 CompleteCalc 클래스는 인터페이스 형 변수로 형변환 될 수 있다.
- 형변환된 경우 인터페이스에 선언된 메서드만 사용 가능하다.
- 클래스는 여러개의 인터페이스를 implement 할 수 있다. (여러 개의 타입을 내포할 수 있음)
package ch11;
public class CalculatorTest {
public static void main(String[] args) {
int num1 = 10;
int num2 = 2;
Calc calc = new CompleteCalc(); // 인터페이스 형 변수로 형변환
System.out.println(calc.add(num1,num2));
System.out.println(calc.substract(num1, num2));
System.out.println(calc.divide(num1, num2));
System.out.println(calc.times(num1, num2));
}
}
수행 결과
12
8
5
20
인터페이스 사용 이유
- 사람과 TV를 연결해주는 리모컨을 생각해보면, 사람은 리모컨의 동작 원리는 몰라도 버튼을 눌러 작동시킬 수 있다.
- 인터페이스는 구현하는 클래스나 프로그램이 제공하는 기능을 명시적으로 선언해놓은 것이다.
- 프로그램을 제공하는 모듈인 서버 코드와 사용하는 쪽의 클라이언트 코드가 있을 때 클라이언트는 서버가 어떻게 구현되어 있는지 모르고 쓰는 경우가 많다.
- 이럴 때 클라이언트는 인터페이스의 메서드를 보고 사용한다.
- 인터페이스에는 어떤 메서드를 호출해서 어떤 매개변수를 주면 어떤 반환값을 주는지 명세되어 있다.
- 어떤 객체가 하나의 인터페이스 타입이라는 것은 그 인터페이스가 제공하는 모든 메서드를 구현했다는 의미이다.
- 인터페이스를 구현한 다양한 객체를 사용하지만 메서드를 사용하는 방식은 동일하다. (다형성)
- 여러 모듈을 바꿔가면서 호출해서 쓸 때, 호출 하는 쪽에서는 코드가 변경될 필요가 없다. 어떤 모듈을 쓰던 사용하는 방식은 동일하기 때문
예시) JDBC 인터페이스
- 자바와 DB를 연결할 때 자바에 정의되어 있는 connection 객체를 이용한다.
- 이때 Connection은 인터페이스이며 이를 구현하는 것은 서버쪽(mySQL, Oracle, MS-SQL ...)이다.
- 서버쪽은 라이브러리인 jar 파일을 생성해 제공한다.
- 클라이언트쪽은 jar 파일이 어떻게 구현되어 있는지 알 필요가 없다.