<정리>
1. 인터페이스란?
1. 구현 코드가 없는 인터페이스
인터페이스는 클래스 혹은 프로그램이 제공하는 기능을 명시적으로 선언하는 역할을 한다.
인터페이스는 추상 메서드와 상수로만 이루어져 있다. 구현 코드가 없기 때문에 인터페이스로 인스턴스를 생성할 수 없다.
public interface Calc {
double PI = 3.14;
int ERROR = -999999999;
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 를 쓰지 않아도 자동으로 추상 메서드로 변환된다.
- public static final 을 쓰지 자동으로 상수로 변환한다.
2. 클래스에서 인터페이스 구현하기
인터페이스에서 선언한 기능을 클래스가 구현한다는 의미로 implements 예약어를 사용한다.
인터페이스의 모든 추상메서드를 구현하지 않은 클래스는 추상 클래스다!
// 추상 클래스
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;
}
Calc 인터페이스에는 추상 메서드 add(), substract(), times(), divide() 4개가 있다.
추상 메서드 times()와 divde()를 구현하지 않았으므로 Calculator는 추상 클래스다.
3. 클래스 완성하고 실행하기
추상 클래스나 인터페이스는 인스턴스를 생성할 수 없다!
실습 코드 참고(CompleteCalc.java / CalculatorTest.java)
4. 인터페이스 구현과 형 변환
인터페이스에서도 하위 자료형은 상위 자료형으로 묵시적 형 변환할 수 있다.
인터페이스를 구현한 클래스가 있을 때 그 클래스는 해당 인터페이스 형으로 묵시적 형 변환할 수 있고 형 변환 되었을 때 사용할 수 있는 메서드는 인터페이스에서 선언한 메서드 뿐이다.
// Calc 인터페이스 형으로 묵시적 형 변환
Calc calc = new CompleteCalc();
- CompleteCalc 클래스는 Calculator 형 이면서, Calc 형이다.
2. 인터페이스와 다형성
1. 인터페이스의 역할
인터페이스는 인터페이스를 구현한 클래스가 어떤 기능의 메서드를 제공하는지 명시하는 역할을 한다.
클라이언트 프로그램은 인터페이스에서 약속한 명세대로 구현한 클래스를 생성해서 사용하면 된다.
2. 인터페이스와 다형성
인터페이스를 사용하면 다형성을 구현하여 확장성 있는 프로그램을 만들 수 있다.
즉, 클라이언트 프로그램을 많이 수정하지 않고 기능을 추가하거나 다른 기능을 사용할 수 있다.
3. 클라이언트가 클래스를 사용하는 방법
클라이언트 프로그램은 각 클래스의 구현 방법을 몰라도 인터페이스에 선언된 매개 변수, 반환 값을 보고 클래스를 사용할 수 있다.
요구사항이 추가되거나 바뀌어도 인터페이스를 구현한 새로운 클래스를 만들어 사용하고 기존에 그것을 사용하는 코드는 수정할 필요가 없다.
// 클래스를 사용하는 코드 수정 필요X
scheduler.getNextCall();
scheduler.sendCallToAgent();
위와 같이 Schduler 인터페이스를 구현한 클래스를 새로 만든다고 해서 클래스를 사용하는 위 코드를 수정할 필요는 전혀 없다.
3. 인터페이스 요소 살펴보기
1. 인터페이스 상수
인터페이스는 추상 메서드로 이루어지므로 인스턴스를 생성할 수 없고 멤버 변수도 사용할 수 없다.
인터페이스에서 선언한 변수는 자동으로 상수로 변환된다.
2. 디폴트 메서드와 정적 메서드
자바 7까지는 인터페이스에서 "추상 메서드와 상수" 만 선언해서 사용할 수 있었다.
인터페이스를 구현한 여러 클래스에서 사용할 메서드가 클래스마다 같은 기능을 제공한다면 각 클래스마다 기능을 반복해 구현해야하는 번거로움이 있었지만,
자바 8부터는 인터페이스 활용성을 높이기 위해 디폴트 메서드와 정적 메서드 기능을 제공한다.
하지만 디폴트 메서드나 정적 메서드를 추가해도 인터페이스는 여전히 인스턴스를 생성할 수 없다.
3. 디폴트 메서드
디폴트 메서드는 인터페이스에서 구현 코드까지 작성한 메서드로 인터페이스를 구현한 클래스에 기본적으로 제공되는 메서드다. 인터페이스에서 구현은 하지만 인터페이스를 구현한 클래스가 생성되면 그 클래스에서 사용할 기본 기능이다.
디폴트 메서드는 일반 메서드와 똑같이 구현하고 메서드 선언시 자료형 앞에 default 예약어를 사용한다.
<디폴트 메서드 재정의하기>
이미 인터페이스에서 구현된 디폴트 메서드가 새로 생성한 클래스에서 원하는 기능과 다르다면 하위 클래스에서 디폴트 메서드를 재정의할 수 있다.
4. 정적 메서드
정적 메서드는 static 예약어를 사용하여 선언하고 인스턴스 생성과 관계없이 사용할 수 있는 메서드다.
정적 메서드는 인터페이스 이름으로 직접 참조하여 사용한다.
5. private 메서드
자바9부터 인터페이스에 private 메서드를 구현할 수 있다.
private 메서드는 인터페이스 내부에서 사용하기 위한 메서드다.
private 메서드는 인터페이스를 구현한 클래스에서 사용하거나 재정의할 수 없다.
private 메서드는 static 예약어와 함께 사용할 수 있는데 다음과 같이 2가지 경우가 있다.
1) private 메서드
인터페이스 내부의 디폴트 메서드에서 사용하기 위한 메서드다.
2) private static 메서드
인터페이스 내부의 정적 메서드에서 호출하여 사용하기 위한 메서드다.
4. 인터페이스 활용하기
1. 한 클래스가 여러 인터페이스를 구현하는 경우
클래스는 메서드 호출이 모호해지는 문제때문에 다중 상속이 불가능하지만,
인터페이스는 한 클래스가 여러 인터페이스를 구현(implements)할 수 있다.
두 인터페이스에 이름이 같은 메서드가 선언되었다고 해도 구현은 클래스에서 이루어지므로 어떤 메서드를 호출해야하는지 모호하지 않기 때문이다.
2. 두 인터페이스의 디폴트 메서드가 중복되는 경우
정적 메서드는 인터페이스명으로 직접 참조하기 때문에 클래스에서 이름이 같은 정적 메서드를 호출하는 것이 문제가 되지 않는다.
// 모호하지 않음
Buy.pay();
Sell.pay();
하지만 디퐅트 메서드는 인스턴스를 생성해야 호출할 수 있기 때문에 이름이 같은 디폴트 메서드가 인터페이스에 있으면 문제가 생긴다.
그러므로 같은 디폴트 메서드가 있다면 인터페이스를 구현하는 클래스에서 디폴트 메서드를 재정의해야한디!
3. 인터페이스 상속하기
인터페이스 간 상속은 구현 코드를 통해 기능을 상속하는 것이 아니므로 형 상속이라고 부른다. 클래스 상속과 마찬가지로 extends 예약어를 사용한다.
클래스는 클래스간 다중 상속이 불가능 하지만 인터페이스는 인터페이스간 다중 상속이 가능하다.
인터페이스를 구현한 클래스는 상위 인터페이스 형으로 형 변환할 수 있지만 형 변환한 상위 인터페이스에 선언한 메서드만 호출할 수 있다.
4. 인터페이스 구현과 클래스 상속 함께 쓰기
5. 실무에서 인터페이스를 사용하는 경우
인터페이스는 클래스가 제공할 기능을 선언하고 설계하는 것이다.
만약 여러 클래스가 같은 메서드를 다르게 구현해야 한다면, 인터페이스에 메서드를 선언하고 각 클래스에서 같은 메서드를 다르게 구현하면 된다. 이것이 바로 인터페이스를 이용한 다형성의 구현이다.
예를들어, 회사에서 시스템을 개발하는데 DB가 정해져있지 않거나 바뀔 가능성이 있다고 하자.
프로그램의 웹/모바일 페이지는 DB와 관계없이 수행되고 DB와 연관된 코드는 프로그램의 특정 부분이다.
이러한 경우 DB 기능을 수행할 인터페이스를 정의하고 여러 DB에 마젝 구현하는 것은 각 클래스가 담당한다.
'Java > Do It! 자바 프로그래밍' 카테고리의 다른 글
[JAVA] 11-2. 기본 클래스_String 클래스 (0) | 2022.05.07 |
---|---|
[JAVA] 11-1. 기본 클래스_Object 클래스 (0) | 2022.05.07 |
[JAVA] 09. 추상 클래스 (0) | 2022.05.06 |
[JAVA] 08. 상속과 다형성 (0) | 2022.05.04 |
[DoItJava] 07. 배열과 ArrayList (0) | 2022.05.04 |