자바의 인터페이스
자바의 인터페이스는 interface 키워드를 사용하여 클래스를 선언하듯이 선언한다.
- PhoneInterface 인터페이스를 선언하는 예
interface PhoneInterface { //인터페이스 선언
public static final int TIMEOUT = 1000; //상수 필드. public static final 생략 가능
public abstract void sendCall(); //추상 메소드. public abstract 생략 가능
public abstract void receiveCall(); //추상 메소드. public abstract 생략 가능
public default void printLogo() { //default 메소드. public 생략 가능
System.out.println("** Phone **");
}; //디폴트 메소드
}
인터페이스 구성
인터페이스는 5종류의 멤버로 구성되며, 필드(멤버 변수)를 만들 수 없다.
1. 상수와 추상 메소드(Java 7까지)
2. default 메소드(Java 8부터)
3. private 메소드(Java 9부터)
4. static 메소드(Java 9부터)
추상 메소드는 public abstract로 정해져 있으며, 생략될 수 있고 다른 접근 지정으로 지정될 수 없다. default, private, static 메소드들은 인터페이스 내에 코드가 작성되어 있어야 한다. default 메소드의 접근 지정은 public으로 고정되어 있다. private 메소드는 인터페이스 내에서만 호출 가능하다. static 메소드는 접근 지정이 생략되면 public이며, private로 지정될 수 있다.
- 인터페이스는 객체를 생성할 수 없다.
인터페이스에 구현되지 않은 추상 메소드를 가질 수 있기 때문에 객체를 생성할 수 없다.
new PhoneInterface(); //오류. 인터페이스 PhoneInterface 객체 생성 불가
- 인터페이스 타입의 레퍼런스 변수는 선언 가능
PhoneInterface apple; //apple은 인터페이스에 대한 레퍼런스 변수
- 인터페이스끼리 상속된다
인터페이스는 다른 인터페이스를 상속할 수 있다.
- 인터페이스를 상속받아 클래스를 작성하면 인터페이스의 모든 추상 메소드를 구현하여야 한다.
자바의 인터페이스는 상속받을 서브 클래스에게 구현할 메소드들의 원형을 모두 알려주어, 클래스가 스스로의 목적에 맞게 메소드를 구현하도록 한다.
인터페이스 구현
인터페이스 구현이란 implements 키워드를 사용하여 인터페이스의 모든 추상 메소드를 구현한 클래스를 작성하는 것을 말한다.
- PhoneInterface를 구현한 SamsungPhone 클래스
class SamsungPhone implements PhoneInterface { //인터페이스 구현
//PhoneInterface의 모든 추상 메소드 구현
public void sendCall() { System.out.println("띠리리리링"); }
public void receiveCall() { System.out.println("전화가 왔습니다."); }
//메소드 추가 작성
public void flash() { System.out.println("전화기에 불이 켜졌습니다."); }
}
PhoneInterface 인터페이스의 모든 추상 메소드를 구현하고, flash() 메소드 추가 작성함. PhoneInterface에 이미 구현되 있는 default 메소드 printLogo()는 그대로 물려받음.
인터페이스 상속
클래스는 인터페이스를 상속받을 수 없고, 인터페이스끼리만 상속이 가능하다. 상속을 통해 기존 인터페이스에 새로운 규격을 추가한 새로운 인터페이스를 만들 수 있으며, 인터페이스의 상속은 extends 키워드를 사용한다.
- PhoneInterface 인터페이스를 상속받아 MobilePhoneInterface
interface MobilePhoneInterface extends PhoneInterface {
void sendSMS(); //추상 메소드
void receiveSMS(); //추상 메소드
}
MobilePhoneInterface 인터페이스는 PhoneInterface 인터페이스의 멤버 뿐만 아니라 sendSMS()와 receiveSMS() 멤버를 가지게 되어 총 6개의 멤버를 가진다. 자바는 인터페이스의 다중 상속을 허용한다.
- MP3Interface 인터페이스
interface MP3Interface {
void play(); //추상 메소드
void stop(); //추상 메소드
}
- 다중 상속 예
interface MusicPhoneInterface extends MobilePhoneInterface, MP3Interface { //다중 상속
void playMP3RingTone(); //추상 메소드
}
위의 코드에서 MusicPhoneInterface는 MobilePhoneInterface와 MP3Interface 인터페이스를 모두 상속 받고, 총 9개의 멤버를 가지게 된다.
인터페이스의 목적
인터페이스는 스펙을 주어 클래스들이 그 기능을 서로 다르게 구현할 수 있도록 하는 클래스의 규격 선언이며, 클래스의 다형성을 실현하는 도구이다.
다중 인터페이스 구현
클래스는 하나 이상의 인터페이스를 구현할 수 있다. 이 경우에 콤마로 각 인터페이스를 구분하여 나열하고, 각 인터페이스에 선언된 모든 추상 메소드를 구현해야 한다.
- AIInterface와 MobilePhoneInterface를 모두 구현한 AIPhone 클래스
interface AIInterface {
void recognizeSpeech(); //음성 인식
void synthesizeSpeech(); //음성 합성
}
class AIPhone implements MobilePhoneInterface, AIInterface { //인터페이스 구현
//MobilePhoneInterface의 모든 메소드를 구현한다
public void sendCall() { ... }
public void receiveCall() { ... }
public void sendSMS() { ... }
public void receiveSMS() { ... }
//AIInterface의 모든 메소드를 구현한다
public void recognizeSpeech() { ... } //음성 인식
public void synthesizeSpeech() { ... } //음성 합성
//추가적으로 다른 메소드를 작성할 수 있다
public int touch() { ... }
}
클래스 상속과 함께 인터페이스 구현
클래스를 상속 받으면서 동시에 인터페이스를 구현할 수 있다. 하지만, 다중 상속과 다중 인터페이스 구현은 너무 남용하면 구조 파악에 어려울 수 있다.
- 인터페이스를 구현하고 동시에 슈퍼 클래스를 상속받는 사례
//SmartPhone.java
interface PhonInterface { //인터페이스 선언
final int TIMEOUT = 10000; //상수 필드 선언
void sendCall(); //추상 메소드
void receiveCall(); //추상 메소드
default void printLogo() { //default 메소드
System.out.println("** Phone **");
}
}
interface MobilePhoneInterface extends PhonInterface { //인터페이스 상속
void sendSMS();
void receiveSMS();
}
interface MP3Interface { //인터페이스 선언
public void play();
public void stop();
}
class PDA { //클래스 작성
public int calculate(int x, int y) {
return x + y;
}
}
//SmartPhone는 PDA를 상속받고, MobilePhoneInterface와 MP3Interface 인터페이스에 선언된 추상 메소드를 모두 구현한다
public class SmartPhone extends PDA implements MobilePhoneInterface, MP3Interface {
//MobilePhoneInterface의 추상 메소드 구현
@Override
public void sendCall() {
System.out.println("따르릉따르릉~~");
}
@Override
public void receiveCall() {
System.out.println("전화 왔어요.");
}
@Override
public void sendSMS() {
System.out.println("문자갑니다");
}
@Override
public void receiveSMS() {
System.out.println("문자왔습니다.");
}
//MP3Interface의 추상 메소드 구현
@Override
public void play() {
System.out.println("음악 연주합니다.");
}
@Override
public void stop() {
System.out.println("음악 중단합니다.");
}
//추가로 작성한 메소드
public void schedule() {
System.out.println("일정 관리합니다.");
}
}
//InerfaceEx.java
public class InerfaceEx {
public static void main(String[] args) {
SmartPhone phone = new SmartPhone();
phone.printLogo();
phone.sendCall();
phone.play();
System.out.println("3과 5를 더하면 " + phone.calculate(3, 5));
phone.schedule();
}
}
인터페이스와 추상 클래스 비교
- 인터페이스와 추상 클래스의 유사점
- 객체를 생성할 수 없고, 상속을 위한 슈퍼 클래스로만 사용된다.
- 클래스의 다형성을 실현하기 위한 목적
- 인터페이스와 추상 클래스의 차이점
비교 | 목적 | 구성 |
추상 클래스 | 서브 클래스에서 구현할 수 밖에 없는 기능만을 추상 메소드로 선언하여, 서브 클래스에서 구현하도록 함(다형성) | 추상 메소드와 일반 메소드 모두 포함 상수, 변수, 필드 모두 포함 |
인터페이스 | 개발자에게 인터페이스를 상속받는 클래스의 목적에 따라 인터페이스의 모든 추상 메소드를 만들도록 함. 객체의 기능을 모두 공개한 표준화 문서와 같음(다형성) | 변수 필드(멤버 변수)는 포함하지 않음 상수, 추상 메소드, 일반 메소드, default 메소드, static 메소드 모두 포함 protected 접근 지정 선언 불가 다중 상속 지원 |
'Java' 카테고리의 다른 글
자바의 상속(캐스팅, 오버라이딩, 추상 클래스) (0) | 2022.03.07 |
---|