본문 바로가기

자바/자바 개념

[Java] 인터페이스 / 2021.11.10

1. 인터페이스란? 

인터페이스는 RS-232인터페이스, USB 인터페이스, SATA 인터페이스 하드디스크 등 컴퓨터 주변 장치에서 많이 사용하는 용어이다. 여기서 인터페이스는 서로 다른 하드웨어 장치들이 상호 데이터를 주고받을 수 있는 규격을 의미한다.

인터페이스의 개념은 소프트웨어에도 적용된다. 소프트웨어를 규격화된 모듈로 만들고, 서로 인터페이스가 맞는 모듈을 조립하듯이 응용프로그램을 작성할 수 있다.

 

2. 자바의 인터페이스

자바에도 인터페이스 개념이 있다. 자바의 인터페이스는 interface 키워드를 사용하여 클래스를 선언하듯이 선언한다. 

 

인터페이스를 선언하는 예

 

interface PhoneInterface { // 인터페이스 선언
    public static final int TIMEOUT = 10000; // 상수 필드, 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 **");
    }; // 디폴트 메소드
}

 

3. 인터페이스 구성

인터페이스는 다음 5종류의 멤버로 구성되며, 필드(멤버 변수)를 만들 수 없다.

 

- 상수와 추상 메소드
- default 메소드
- private 메소드
- static 메소드

 

추상 메소드는 public abstract로 정해져 있으며, 생략 될 수 있고, 다른 접근 지정으로 지정될 수 없다.

default, private, static 메소드들은 모두 인터페이스 내에 코드가 작성되어 있어야 한다.

default 메소드의 접근 지정은 public 으로 고정되어있고, private 메소드는 인터페이스 내에서만 호출 가능하며, static 메소드의 경우 접근 지정이 생략되면 public이며, private로 지정될 수 있다.

 

* 인터페이스는 객체를 생성할 수 없다.

* 인터페이스 타입의 레퍼런스 변수는 선언 가능하다.

* 인터페이스끼리 상속된다.

* 인터페이스를 상속받아 클래스를 작성하면 인터페이스의 모든 추상 메소드를 구현해야한다.

4. 인터페이스 구현

인터페이스 구현이란 implements 키워드를 사용하여 인터페이스의 모든 추상 메소드를 구현한 클래스를 작성하는 것을 말한다. 

예시를 통해 알아보자.

 

package Chapter5;

interface PhoneInterface{ // 인터페이스 선언
	final int TIMEOUT = 10000; // 상수 필드 선언
	void sendCall();           // 추상 메소드
	void receiveCall();        // 추상 메소드
	default void printLogo() { // default 메소드
		System.out.println("** Phone **");
	}
}

class SamsungPhone implements PhoneInterface{ // 인터페이스 구현
	// PhoneInterface의 모든 추상 메소드 구현
	public void sendCall() {
		System.out.println("띠리리리링");
	}
	public void receiveCall() {
		System.out.println("전화가 왔습니다.");
	}
	
	// 메소드 추가 작성
	public void flash() {
		System.out.println("전화기에 불이 켜졌습니다.");
	}
}

public class InterfaceEx {
	 public static void main(String[] args) {
		 SamsungPhone phone = new SamsungPhone();
		 phone.printLogo();
		 phone.sendCall();
		 phone.receiveCall();
		 phone.flash();
	 }
}

 

SamsungPhone 클래스에는 PhoneInterface 인터페이스의 모든 추상 메소드를 구현하고, flash() 메소드를 추가 작성하였으며, PhoneInterface에 이미 구현되어 있는 default printLogo()는 그대로 물려받는다.

 

실행 결과 :

 

 

5. 인터페이스 상속

클래스는 인터페이스를 상속받을 수 없고, 인터페이스끼리만 상속이 가능하다. 상속을 통해 기존 인터페이스에 새로운 규격을 추가한 새로운 인터페이스를 만들 수 있으며, 인터페이스 상속은 extends 키워드를 사용한다.

 

위의 예제에 PhoneInterface 인터페이스를 상속받아 MobilePhoneInterface 인터페이스를 추가해보자.

 

interface MobilePhoneInterface extends PhoneInterface{
    void sendSMS(); // 추상 메소드
    void receiveSMS(); // 추상 메소드
}

 

이렇게 하면 MobilePhoneInterface 인터페이스는 PhoneInterface의 4개 멤버에 2개의 멤버를 추가한 총 6개의 멤버를 가지게 된다. 

 

* 인터페이스는 다중 상속을 허용한다.

 

6. 인터페이스의 목적

인터페이스를 사용하면 다형성이 실현된다. 예를 들어 앞의 MobilePhoneInterface로 SamsungPhone과 LGPhone 클래스를 만들면 두 클래스 모드 인터페이스에 나열된 메소드와 동일한 이름의 메소드를 구현하겠지만, 삼성과 LG가 구현한 내용은 서로 다를 것이다.

 

7. 다중 인터페이스 구현

클래스는 하나 이상의 인터페이스를 구현할 수 있다. 이 경우 콤마로 각 인터페이스를 구분하여 나열하며, 각 인터페이스 선언된 모든 추상된 메소드를 구현하여야 한다. 그렇지 않으면 컴파일 오류가 생긴다.

 

클래스 상속과 함께 인터페이스를 구현해보자.

클래스를 상속 받으면서 동시에 인터페이스를 구현할 수 있다. 다중 상속, 다중 인터페이스 구현은 유용하나 자칫 너무 남용하면 클래스, 인터페이스 간의 관계가 너무 복잡해져 프로그램 전체 구조를 파악하기 어려울 수 있으므로 주의하는 것이 좋다.

 

package Chapter5;

interface PhoneInterface{ // 인터페이스 선언
	final int TIMEOUT = 10000; // 상수 필드 선언
	void sendCall();           // 추상 메소드
	void receiveCall();        // 추상 메소드
	default void printLogo() { // default 메소드
		System.out.println("** Phone **");
	}
}

interface MobilePhoneInterface extends PhoneInterface {
	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를 상속받고,
// MobliePhoneInterface와 MP3Interface 인터페이스에 선언된 추상 메소드 모두 구현
class SmartPhone extends PDA implements MobilePhoneInterface, MP3Interface{
	public void sendCall() {
		System.out.println("따르릉따르릉~~");
	}
	public void receiveCall() {
		System.out.println("전화 왔어요.");
	}
	public void sendSMS() {
		System.out.println("문자갑니다.");
	}
	public void receiveSMS() {
		System.out.println("문자왔어요.");
	}
	
	public void play() {
		System.out.println("음악 연주합니다.");
	}
	public void stop() {
		System.out.println("음악 중단합니다.");
	}
	// 추가로 작성한 메소드
	public void schedule() {
		System.out.println("일정 관리합니다.");
	}


public class InterfaceEx {
	 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();
	 }
}

 

8. 인터페이스와 추상 클래스 비교 

인터페이스와 추상 클래스의 유사한 점

- 객체를 생성할 수 없고, 상속을 위한 슈퍼 클래스로만 사용된다.

- 클래스의 다형성을 실현하기 위한 목적이다.

 

인터페이스와 추상 클래스의 다른 점

 

비교 목적 구성
추상 클래스 추상 클래스는 서브 클래스에서 필요로 하는 대부분의 기능을 구현하여 두고 서브 클래스가 상속받아 활용할 수 있도록 하되, 서브 클래스에서 구현할 수 밖에 없는 기능만을 추상 메소드로 선언하여, 서브 클래스에서 구현하도록 하는 목적 (다형성) - 추상 메소드와 일반 메소드 모두 포함
- 상수, 변수 필드 모두 포함
인터페이스 인터페이스의 객체의 기능을 모두 공개한 표준화 문서와 같은 것으로, 개발자에게 인터페이스를 상속받는 클래스의 목적에 따라 인터페이스의 모든 추상 메소드를 만들도록 하는 목적 (다형성) -변수 필드(멤버 변수)는 포함하지 않음
- 상수, 추상 메소드, 일반 메소드, default 메소드, static 메소드 모두 포함
- protected 접근 지정 선언 불가
- 다중 상속 지원