인터페이스는 추상클래스와 비슷합니다. 인터페이스는 추상클래스와 같이 추상메소드를 갖지만 추상클래스 이상으로 추상화가 높습니다! 추상클래스 같은 경우 몸통이 있는 일반 메소드와 멤버 변수를 허용하였지만, 인터페이스 같은 경우 몸통이 있는 일반 메소드 또는 멤버 변수를 허용하지 않아, 구성원으로 가질 수 없습니다.
오직 추상 메소드와 상수만을 멤버로 가질 수 있으며, 그 외 허용하지 않는다.
추상 클래스를 부분적으로 완성 된 설계도라고 부른다면, 인터페이스는 밑그림 스케치 정도만 있는 설계도라고 보면 될 것 같습니다!
인터페이스도 추상클래스 처럼 불완전한 클래스 이다 보니, 그 자체만으로 사용 할 수는 없습니다! 따라서 다른 클래스를 작성하는데 도움을 줄 목적으로 사용됩니다!
작성 예시
인터페이스는 클래스와 작성 방법은 같지만 class 라는 키워드 대신 interface라는 키워드를 사용한다. 그리고 interface에도 class 와 같이 접근제어자로 public 또는 default를 붙일 수 있다.
작성 예시에는 현재 아무것도 붙여 있지 않아 임의로 default가 붙여있는 형태이다.
interface 인터페이스이름 { public static final 타입 상수이름 = 값; public abstract 메소드 이름(매개변수목록); }
제약 사항
일반적인 클래스와 달리 인터페이스는 제약사항이 있다.
모든 멤버 변수는 public static final 이어야 하며, 이를 생략할 수 있다.
모든 메소드는 public abstract 이어야 하며, 이를 생략할 수 있다.
- static 메소드와 디폴트 메소드만 제외 하고 가능(JDK 1.8부터)
인터페이스에 정의된 모든 멤버에 예외 없이 적용 되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많습니다. 생략된 제어자는 컴파일 시에 컴파일러가 자동적으로 추가해준다.
interface PlayingCard {
public static final int SPADE = 4;
final int DIAMOND = 3; // public static final DIAMOND = 3;
static int HEART = 3; // public static final HEART = 3;
int CLOVER = 1; // public static final CLOVER = 1;
public abstract String getCardNumber();
String getCardKing(); // public abstract String getCardKing();
}
인터페이스는 인터페이스로만 상속을 받을 수 있으며, 인터페이스는 클래스, 추상클래스와 다르게 다중상속, 여러개의 인터페이스를 상속 받을 수 있다.
interface Movable {
/* 지정된 위치(x,y)로 이동하는 기능의 메소드 */
void move(int x, int y);
}
interface Attackable {
/* 지정된 대상(u)을 공격하는 기능의 메소드 */
void attack(Unit u);
}
interface Fightable extends Movable, Attackable {
}
클래스의 상속과 마찬가지로 자식 인터페이스는 부모 인터페이스에 정의된 멤버를 모두 상속받는다.
그래서 Fightable에는 정의 된 멤버가 없지만 부모 인터페이스로 부터 상속을 받아, Movable, Attackable가 멤버로 존재 하는 것이다.
인터페이스도 추상클래스와 마찬가지로 인스턴스를 생성할 수 없습니다.
추상클래스도 상속을 통해 추상메소드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상메소드의 몸통을 만들어주는 클래스를 작성해야 합니다. 추상클래스 같은경우 extends로 상속을 받았다면, 인터페이스 같은 경우, implements로 상속을 받습니다.
class 클래스이름 implements 인터페이스이름 { // 인터페이스에 정의된 추상메소드를 구현해야 한다. } class Fighter implements Fightable { public void move(int x, int y) { /* 내용 생략 */ } public void 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) {
/* 내용 생략*/
}
}
- 개발 시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능하다.