인터페이스(interface)란?
우리들은 컴퓨터를 사용할 때 화면에서 제공하는 기능만을 사용할 수 있으며 이런 화면을 인터페이스라고 한다. 자바에서 말하는 인터페이스 또한 이와 다르지 않다. 즉, 클래스를 사용하는 개발자에게 사용할 수 있는 정보만을 제공하는 역할을 수행하는 것이다.
인터페이스는 추상 클래스와 구조적으로 크게 다른 것은 없으며 추상화 정도가 더 높을 뿐이다. 추상 메서드를 갖지만 일반 메서드 또는 멤버 변수를 가질 수 없다는 특징이 있으며, 추상 클래스와 마찬가지로 추상 메서드에 대한 구현을 강제한다.
인터페이스의 구조는 다음과 같다.
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수 목록);
}
인터페이스에 대한 제약사항과 간단한 예제를 살펴보자.
- 모든 멤버 변수는 public static final 이어야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. (단, static 메서드와 디폴트 메서드는 예외 java8부터 / private 메서드 사용가능 java9부터)
※ 인터페이스 내에 default는 접근제어자가 아닌 해당 메서드가 추상 메서드가 아님을 명시하는 키워드이다. 디폴트 메서드의 경우 인터페이스를 상속받는 클래스들이 해당 메서드를 오버라이딩할 필요가 없다.
//정상적인 선언
interface PlayingCard {
public static final int SPADE = 4;
final int DIAMOND = 3; //public static final int DIAMOND = 3;
static int HEART = 2; //public static final int HEART = 2;
int CLOVER = 1; //public static final int CLOVER = 1;
public abstract String getCardNumber();
String getCardKind(); //public abstract String getCardKind();
}
아직 추상 클래스와 인터페이스의 차이점에 대해 명확하지 않을 수 있기 때문에 좀 더 알아보자.
추상 클래스는 그 자체로는 객체를 생성할 수 없기 때문에 추상 클래스를 상속받아 클래스를 구현해야 한다. 즉, 추상 클래스의 의미는 기본적인 구조를 상속받는 클래스가 가짐과 동시에 이를 구현하고 확장하는데 초점을 맞춘 것이다.
그렇다면 인터페이스의 경우는 어떨까? 인터페이스를 상속받는 클래스는 인터페이스에 선언된 메서드에 대해 구현은 가능하지만, 자신만의 메서드를 확장할 경우는 이에 대해 접근할 방법이 없다. 즉, 인터페이스는 미리 사용할 메서드에 대해 규칙 또는 범위를 정해놓은 것이다.
인터페이스의 상속과 구현
인터페이스는 인터페이스로부터만 상속이 가능하며, 클래스와 달리 다중상속이 가능하다. 책의 예제를 통해 확인해보자.
interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit u);
}
interface Fightable extends Movable, Attackable { }
인터페이스 Fightable은 상위 인터페이스(Movable, Attackable)에 정의된 멤버(move(int x, int y), attack(Unit u))를 상속 받는다.
위에서 정의한 인터페이스를 이용해 책에서 소개한 간단한 예제를 구현해보자.
// 만약 인터페이스의 메서드 중 일부만 구현하는 경우, abstract를 붙여 추상 클래스로 선언해야 한다.
abstract class Fighter implements Fightable {
public void move(int x, int y) {
//...
}
}
// 상속과 구현을 동시에 하는 경우
class Fighter extends Unit implements Fightable {
public void move(int x, int y) {
//...
}
public void attack(Unit u) {
//...
}
}
인터페이스를 이용한 다형성
인터페이스 또한 이를 구현한 클래스의 상위 타입이라고 할 수 있으므로 인터페이스에도 다형성이 적용될 수 있다. 이전 코드를 이용해 간단한 예제를 확인해보자.
void method(Fightable fightable) {
//...
}
Fightable fightable = (Fightable)new Fighter(); //형변환 생략가능
method(fightable);
method(new Fighter());
매개변수로 인터페이스 타입을 받는 경우, 해당 매개변수로 인터페이스를 구현한 클래스의 인스턴스를 넘겨주어야 한다.
※ 인터페이스 타입은 메서드의 반환 타입이 될 수도 있다. (해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 의미)
인터페이스의 장점
1. 표준화가 가능하다.
기본 틀을 인터페이스로 작성 후 프로그램을 구현함으로써 일관되고 정형화된 개발이 가능해진다.
2. 개발시간을 단축시킬 수 있다.
프로그램 작성 시 인터페이스의 메서드 선언부만 알면 실제 구현 여부에 관계없이 개발이 가능해진다.
3. 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
인터페이스를 상위 타입으로 지정하여 서로 관련없는 클래스 간에 연결관계를 형성할 수 있다.
4. 독립적인 프로그래밍이 가능하다.
인터페이스를 이용해 클래스와 클래스 간의 직접적인 관계를 간접적인 관계로 변경 가능하다. 클래스에서 다른 클래스를 인터페이스 타입으로 주입받는 경우 인터페이스의 구현 클래스가 변경되어도 인터페이스를 주입받는 클래스의 내용에는 변경이 없다.
Q&A
Q. 인터페이스란?
A. 클라이언트에겐 사용할 수 있는 멤버에 대한 정보를 제공하고, 구현 클래스에겐 구현해야 하는 메서드를 강제하는 일종의 추상 클래스이다.
Q. 접근제어자 default와 인터페이스의 디폴트 메서드의 차이는?
A. 접근제어자 default는 해당 클래스에 대한 접근 범위를 의미하고, 인터페이스의 디폴트는 해당 클래스가 추상 클래스가 아님을 정의하는 키워드이다.
Q. 인터페이스의 장점은?
A. 표준화를 통해 개발 시간 단축이 가능하고, 독립적인 프로그래밍이 가능하며, 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
참고자료
- Java의 정석
'개념서 > Java' 카테고리의 다른 글
| [Java] 예외처리 (0) | 2022.06.27 |
|---|---|
| [Java] 내부 클래스 (0) | 2022.06.25 |
| [Java] 다형성 (0) | 2022.06.17 |
| [Java] 제어자 (0) | 2022.06.13 |
| [Java] package와 import (0) | 2022.06.10 |
댓글