💡 인터페이스는 여러 클래스에서 사용할 멤버(필드, 메서드) 를 일관되게 하기 위한 기술 명세이다.
아이폰과 갤럭시를 위한 프로그램을 개발한다고 생각해보자. 두 스마트폰은 구현 방식과 실행 플랫폼이 다르므로 각각 전용 프로그램을 개발해야하고, 사용자 또한 아이폰과 갤럭시 두 스마트폰 모두 프로그램 사용법을 익혀야 할 것이다. 그럼 구현 방식과 실행 플랫폼은 다르더라도, 사용법만은 일관되게 하려면 어떻게 해야할까? 그것은 바로 다음과 같은 기준을 정함으로써 가능하다.
즉 이렇게 기준을 정함으로써(=인터페이스를 통일함으로써) 사용자는 플랫폼에 상관없이 일관된 방법으로 프로그램을 사용할 수 있다.
자바에서는 인터페이스(interface)
가 위의 역할을 해주며, 이로 인해 프로그램을 개발하기 전에 기능별로 클래스, 변수, 메서드를 정할 수 있다. 인터페이스는 여러 클래스에서 사용할 멤버(필드, 메서드) 를 일관되게 하기 위한 기술 명세
인 것이다.
자바에서 인터페이스는 다음과 같이 선언한다. 인터페이스에서 멤버를 선언할 때 접근 제한자는 반드시 public
으로 선언할 것에 유념한다.
제어자 interface 인터페이스명 {
// 모든 멤버의 접근 제한자는 public으로 선언
public static fianl 변수 선언;
public abstract 메서드 선언(); // 구현부 없음(추상 메서드)
public default 메서드 선언() {}
public static 메서드 선언() {}
}
선언 문법에서 확인할 수 있듯이, 인터페이스는 자체적으로 속성과 기능을 가진 객체는 아니고, 다른 클래스에서 구현할 내용에 대해 형식만 갖춘 것이다.
public interface Messenger {
int MIN_SIZE = 1; // 컴파일 시 'public static final' 제어자 자동으로 추가
int MAX_SIZE = 104857600; // 컴파일 시 'public static final' 제어자 자동으로 추가
}
public static final
을 지정하지 않으면 컴파일러가 컴파일 시 자동으로 이를 추가한다.// 인터페이스 본문에 메서드 선언
public String getMessage();
public String setMessage(String msg);
// 메서드는 컴파일 시 abstract 제어자가 자동으로 추가된다.
public abstract String getMessage();
public abstract String setMesage(String msg);
public abstract
제어자가 자동으로 추가된다.자바 7
까지는 인터페이스에 public static final 필드와 public abstract 메서드 선언만 가능했으나, 자바 8
부터 default 메서드
, static 메서드
가 추가되어 본문을 갖는 메서드를 인터페이스에 선언할 수 있게 되었다.
public default void setLogin(boolean login) {
if (login) {
System.out.println("로그인 처리합니다");
else {
System.out.println("로그아웃 처리합니다.");
}
}
public static void getConnection() {
System.out.println("network에 연결합니다");
}
static 메서드
는 해당 인터페이스를 구현하고 있는 모든 객체에서 자주 사용하는 유용한 기능을 제공하기 위해서 사용된다 .private void log() { // 같은 인터페이스의 default 메서드에서 사용하기 위해 선언된 private 메서드
System.out.println("start job!");
}
default void setLogin() { // default 메서드에서 private 메서드를 사용한다(같은 인터페이스 내).
log();
}
private 메서드
는 동일한 인터페이스에 선언된 default메서드에서 사용할 목적으로 본문을 구현하는 메서드이다./* 인터페이스 예제 코드 Messenger.java */
public interface Messenger {
public static final int MIN_SIZE = 1; // 'public static final' 생략시 자동으로 추가
public static final int MAX_SIZE = 104857600;
public abstract String getMessage(); // 'abstract' 생략 시 자동으로 추가
public abstract void setMessage(String msg);
// default 메서드 : 인터페이스를 사용하는 모든 클래스에서 공통으로 갖는 기능을 구현
default void setLogin(boolean login) {
log();
if (login) {
System.out.println("로그인 처리합니다.");
} else {
System.out.println("로그아웃 처리합니다.");
}
}
// static 메서드 : 인터페이스를 구현하는 모든 객체에서 자주 사용하는 유용한 기능을 제공
public static void getConnection() {
System.out.println("network에 연결합니다.");
}
// private 메서드 : 동일한 인터페이스에 선언된 default 메서드에서만 사용할 목적으로 본문을 구현하는 메서드
private void log() {
System.out.println("start job!");
}
}
extends 클래스명
으로 선언하고, 인터페이스를 상속할 때는 implements 클래스명
으로 선언한다.제어자 class 클래스명 extends 부모 클래스명 implements 인터페이스명 {
}
/* Messenger 인터페이스 */
public interface Messenger {
public static final int MIN_SIZE = 1;
public static final int MAX_SIZE = 104857600;
public abstract String getMessage();
public abstract void setMessage(String msg);
default void setLogin(boolean login) {
log();
if (login) {
System.out.println("로그인 처리합니다.");
} else {
System.out.println("로그아웃 처리합니다.");
}
}
public static void getConnection() {
System.out.println("network에 연결합니다.");
}
private void log() {
System.out.println("start job!");
}
}
/* Messenger 인터페이스를 상속하는 IPhoneManager, GalaxyManager 클래스 */
public class IPhoneManager implements Messenger {
}
public class GalaxyManager implements Messenger {
}
위처럼 Messenger
인터페이스를 상속하면 곧바로 컴파일 오류가 발생하는데, 이것은 인터페이스를 상속한 클래스에서 인터페이스의 추상메서드를 오버라이딩 해주지 않았기 때문이다. 추상메서드를 포함하는 인터페이스를 상속하는 클래스는 반드시 추상 메서드를 오버라이딩 해주어야한다.
public class IPhoneMessenger implements Messenger {
public String getMessage() { // 오버라이딩
return "iphone";
}
public void setMessage(String msg) { // 오버라이딩
System.out.println("iPhone에서 메시지를 설정합니다 : " + msg);
}
public void clearMessage() {
System.out.println("좌우로 흔들어 문자열을 지웁니다.");
}
}
public class GalaxyMessenger implements Messenger{
public String getMessage() { // 오버라이딩
return "galaxy";
}
public void setMessage(String msg) { // 오버라이딩
System.out.println("galaxy에서 메시지를 설정합니다 : " + msg);
}
public void changeKeyboard() {
System.out.println("키보드아이콘 터치 후 키보드를 변경합니다.");
}
}
// 인스턴스 생성 후 사용 예제
public class MessengerTest {
public static void main(String[] args) {
IPhoneMessenger iphone = new IPhoneMessenger();
GalaxyMessenger galaxy = new GalaxyMessenger();
System.out.println("메신저 최소 문자크기 : " + Messenger.MIN_SIZE);
System.out.println("메신저 최대 문자크기 : " + Messenger.MAX_SIZE);
iphone.setLogin(true);
iphone.getMessage();
iphone.setMessage("hello");
iphone.clearMessage();
galaxy.setLogin(true);
galaxy.getMessage();
galaxy.setMessage("hi");
galaxy.changeKeyboard();
}
}
이처럼, 인터페이스를 만들고 비슷한 기능을 처리하는 곳에서 인터페이스를 상속하여 구현하면 일관된 구조를 가질 수 있고 유지 보수하기가 수월해진다.
제어자 class 클래스명 extends 부모클래스명 implements 인터페이스명, 인터페이스명, ... {
}
// WorkFile.java
public interface WorkFile {
public void fileUpload(); // 컴파일 시 abstract 자동으로 추가
public void fileDownload(); // 컴파일 시 abstract 자동으로 추가
}
// Messeger, WorkFile 인터페이스를 상속하는(다중 상속) GalaxyMessenger 클래스
public class GalaxyMessenger implements Messenger, WorkFile{
public String getMessage() { // Messenger 인터페이스 메서드 오버라이딩
return "galaxy";
}
public void setMessage(String msg) { // Messenger 인터페이스 메서드 오버라이딩
System.out.println("galaxy에서 메시지를 설정합니다 : " + msg);
}
public void fileUpload() { // WorkFile 인터페이스 오버라이딩
System.out.println("file을 업로드합니다.");
}
public void fileDownload() { // WorkFile 인터페이스 오버라이딩
System.out.println("file을 다운로드합니다.");
}
public void changeKeyboard() {
System.out.println("키보드아이콘 터치 후 키보드를 변경합니다.");
}
}
// GraphicIOS.java
public class GraphicIOS {
public void draw_textBox() {
System.out.println("텍스트 상자를 그린다.");
}
public void draw_submitButton() {
System.out.println("전송 버튼을 그린다.");
}
}
// GraphicIOS 클래스와 Messenger 인터페이스를 상속하는 (복합 상속) IphoneMessenger 클래스
public class IPhoneMessenger extends GraphicIOS implements Messenger {
public String getMessage() { // 오버라이딩
return "iphone";
}
public void setMessage(String msg) { // 오버라이딩
System.out.println("iPhone에서 메시지를 설정합니다 : " + msg);
}
public void clearMessage() {
System.out.println("좌우로 흔들어 문자열을 지웁니다.");
}
}
✍ 본 포스팅은 책 ‘처음 해보는 자바 프로그래밍(오정임 저, 루비페이퍼)’을 읽고 정리한 글입니다.