서로 다른 장치들이 연결되어 상호 데이터를 주고 받는 규격을 의미한다.
하드웨어 장치를 생각해보자.
서로 다른 pc 를 사용하지만 usb 를 연결하는 장치는 동일하다.
안드로이드 폰을 이용하면 다른 기종이라 하더라도 같은 종류의 충전 장치를 가진다.
소프트웨어에서의 인터페이스도 비슷하다.
서로 다른 클래스를 연결할 때 규격이 존재한다면 클래스들이 잘 접속할 수 있을 것이다. 이 규격이 인터페이스다.
인터페이스 정의
interface RemoteControl {
public abstract void on(); // public abstract 생략가능
void off();
}
추상 클래스와 동일한 문법으로 정의할 수 있다.
만약 서로 다른 리모컨을 만든다고 가정을 해보자.
각기 다른 회사에서 리모컨을 만든다면 각자의 코드를 만들게 될 것이다.
class Rmc1 {
public void on() {
System.out.println("Rmc1 리모컨이 켜집니다");
}
public void off() {
System.out.println("Rmc1 리모컨이 꺼집니다");
}
}
class Rmc2 {
public void hello() {
System.out.println("Rmc2 리모컨이 켜집니다");
}
public void bye() {
System.out.println("Rmc2 리모컨이 꺼집니다");
}
이런 코드로 작성이 되면 각 제조사들 간의 가전제품에서는 사용가능할 수 있으나, 만능 리모컨이나 다양한 가전제품을 연결해서 사용하는 홈네트워크 서버 등에는 활용이 어려울 것이다.
그래서 이 사이에 합의가 필요한데 이때 인터페이스를 사용하고, 하위 클래스는 implement 키워드를 이용한다.
interface RemoteControl {
public abstract void turnOn();
public abstract void turnOff();
}
class Rmc1 implements RemoteControl {
public void turnOn() {
System.out.println("Rmc1 리모컨이 켜집니다.");
}
public void turnOff() {
System.out.println("Rmc2 리모컨이 꺼집니다.");
}
}
class Rmc2 implements RemoteControl {
public void turnOn() {
System.out.println("Rmc2 리모컨이 켜집니다.");
}
public void turnOff() {
System.out.println("Rmc2 리모컨이 꺼집니다.");
}
}
public class example11 {
public static void main(String[] args) {
RemoteControl r1 = new Rmc1();
RemoteControl r2 = new Rmc2();
r1.turnOn();
r2.turnOff();
}
}
RemoteControl 이라는 인터페이스를 만들었다.
이렇게 되면 Rmc1 리모컨과 Rmc2 리모컨은 turnOn, turnOff 메서드를 사용하지 않으면 오류가 난다.

인터페이스는 연산자가 아니므로 메모리에 띄울 수 없다.
인터페이스와 추상 클래스의 차이
인터페이스와 추상 클래스는 유사한 점을 가지고 있다. 비슷한 문법을 가지고 있고, 구현이 되지 않는 메서드를 가지고 있다. 차이를 비교해보자

우선 첫번째 그림을 보자
자동차는 운송수단인가? yes . 비행기는 운송수단인가? yes , 기차는 운송수단인가? yes
이렇다면 자동차는 운송수단이라는 추상 클래스를 구체화한 객체이다.
이때는 상속을 사용한다.

TV는 리모컨인가? NO, 홈시어터는 리모컨인가? NO, 스피커는 리모컨인가 ? NO
각 객체는 리모컨과 상관없지만 동일한 on off 기능을 포함하고 싶을 때 인터페이스를 사용한다.
클래스들 사이에서 코드를 공유하고 싶다면 추상 클래스, 관련 없는 클래스들이 동일한 동작을 구현하기 위해선 인터페이스를 이용하자.
Share article