1. 인터페이스 개요
인터페이스(interface)란
- 역할 부여를 위한 개념
- 코드 수행부가 없는 추상 메소드(abstract method)로 구성
- 오버라이딩을 통한 다양한 동작을 목적으로 함
- 프로그램 설계를 명확히 하고 다영성을 통해 프로그램의 유연성을 도움
- 다형성(polymorphism)
- 한 대상이 다양한 형태로 동작 또는 해석되는 것
- 유연성(flexibility)
- 다양한 요구사항을 수용하는 성질
- 다형성(polymorphism)
- default 메소드와 static 메소드 및 상수도 포함 가능
인터페이스 사용 예
인터페이스 정의
- 추상 메소드는 인터페이스로 정의가 가능
- 여러 개 동시에 상속 가능
- abstract는 불가 → 오로지 하나의 부모 클래스만 있어야 함
- 객체의 역할을 인터페이스로 정의
- ex. 인터페이스 정의 예시
1 2 3 4
interface 인터페이스명 { abstract public void 메소드명A(); void 메소드명B(); // 입력을 안할시 자동으로 abstract public이 들어감 }
인터페이스 구현
- 정의된 인터페이스는 구현을 통해 특정 클래스에 부여 가능 → 구현체 클래스
implements
- 구현을 명시하는 키워드
A implements B
형태로 사용
- 2개 이상의 인터페이스 한번에 상속 가능 (다중 상속)
- ex. 인터페이스 구현 예시
1 2 3 4 5 6 7
class 클래스명 implements 인터페이스명 { public void 메소드명A(String a) { // 인터페이스를 만들 때 public이 자동으로 들어가기 때문에 public void 를 써주어야 함 System.out.printf("%s 메소드명A!!", a); } public void 메소드명B(){} // 인터페이스의 모든 추상 메소드는 수행부가 없기 때문에 반드시 재정의해주어야 한다. // 메소드 오버라이딩을 하기 위해 }
➣ 상속(extend) vs 구현(implement)
상속(extend) | 구현(implement) | |
---|---|---|
의미 | 자신의 기능을 하위 클래스로 확장 | 메소드들을 목적에 맞게 기능 구현 |
구현 기반 | 일반 class, abstract class | interface |
다중 상속 여부 | X | O |
재정의(overriding) 여부 | 선택 | 필수 |
인터페이스 수행
- 객체는 자신이 구현하는 인터페이스로 업 캐스팅(해석) 될 수 있음
- 객체는 인터페이스의 추상 메소드 호출을 통해 메소드 오버라이딩 진행
- ex. 인터페이스 수행 예시
1 2 3
클래스명 c = (클래스명) new 인터페이스명(); // 업캐스팅'(클래스명)'은 생략 가능 c.메소드명A("new a"); // 메소드 오버라이딩: 구현체 클래스의 재정의 메소드를 수행 c.메소드명B(); // 메소드 오버라이딩
2. 인터페이스와 다형성
인터페이스 다중 구현
- 클래스는 다양한 인터페이스를 동시에 구현 가능
- ex.
SmartPhone
클래스의 다양한 역할 구현 예시1
class SmartPhone implements Alarm, Phone, Messenger{구현 내용}
객체의 다형성
- 객체는 자신이 구현하는 인터페이스 타입으로 해석(업 캐스팅) 될 수 있음
- 인터페이스로 해석된 객체 사용 가능
- 객체의 해석은 레퍼런스변수의 타입이 결정
- 해석 영역을 벗어난 사용은 수행 불가
- ex.
SmartPhone
객체를 인터페이스 타입으로 해석 예시1 2
SmartPhone sp = new SmartPhone(); Alarm alarm = sp; // SmartPhone 객체를 Alarm으로 해석
인터페이스의 다형성
- 서로 다른 객체 → 같은 인터페이스 구현
- 공통된 인터페이스로 다양한 동작 관리 가능
- ex. 공통된 인터페이스를 통한
ArrayList
생성 및 출력하기1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
interface Flyable { // 상위 인터페이스 생성 void fly(); } class Bird implements Flyable { // 구현체 클래스(Bird) 생성 public void fly() { System.out.println("[Bird]가 날개를 퍼덕이며 날아갑니다!"); } } class Helicopter implements Flyable { // 구현체 클래스(Helicopter) 생성 public void fly() { System.out.println("[Helicopter]가 프로펠러를 돌리며 날아갑니다!"); } } class Rocket implements Flyable { // 구현체 클래스(Rocket) 생성 public void fly() { System.out.println("[Rocket]이 불꽃을 뿜으며 날아갑니다!"); } } public class FlyWithInterface { public static void main(String[] args) { // 객체 생성 Bird b = new Bird(); Helicopter h = new Helicopter(); Rocket r = new Rocket(); Flyable[] arr = { b, h, r }; // 상위 인터페이스 타입으로 배열화 for (int i = 0; i < arr.length; i++) { arr[i].fly(); // 인터페이스를 통한 오버라이딩 } } }
- ex 실행 결과
1 2 3
[Bird]가 날개를 퍼덕이며 날아갑니다! [Helicopter]가 프로펠러를 돌리며 날아갑니다! [Rocket]이 불꽃을 뿜으며 날아갑니다!