1. 인터페이스 역할
- 인터페이스는 객체의 사용 방법을 정의한 타입
- 인터페이스는 객체의 교환성을 높여주기 때문에 다형성을 구현하는데 매우 중요한 역할
- 인터페이스는 개발 코드와 객체가 서로 통신하는 접점 역할
- 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출
- 개발 코드는 객체의 내부 구조를 알 필요가 없고 인터페이스의 메소드만 알고 있으면 됩니다.
왜 중간에 인터페이스를 두는 가요?
- 개발 코드를 수정하지 않고, 사용하는 객체를 변경할 수 있도록 하기 위해서입니다.
- 인터페이스는 하나의 객체가 아니라 여러 객체들과 사용이 가능하므로 어떤 객체를 사용하느냐에 따라서 실행 내용과 리턴 값이 다를 수 있습니다. (다형성)
- 객체 교환을 이용해서 다양한 리턴 값을 반환받을 수 있습니다. (부품화)
2. 인터페이스 선언
public interface 인터페이스명 {
// 상수
타입 상수명 = 값;
// 추상 메소드
타입 메소드명(매개변수, ...);
// 디폴트 메소드
default 타입 메소드명(매개변수, ...) {
...
}
// 정적 메소드
static 타입 메소드명(매개변수, ...) {
...
}
}
- 인터페이스는 상수와 메소드만을 구성 멤버로 가집니다.
- 인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없습니다.
- 자바 7 이전까지는 인터페이스의 메소드는 실행 블록이 없는 추상 메소드로만 선언이 가능
- 자바 8부터는 디폴트 메소드와 정적 메소드도 선언이 가능
3. 인터페이스 구성요소
상수 필드 (Constant Field)
[public static final] 타입 상수명 = 값;
- 인터페이스는 런타임 시 데이터를 저장할 수 있는 필드(인스턴스, 정적필드)를 선언할 수 없습니다.
- 상수를 선언할 때는 반드시 초기값을 대입해야 합니다.
- 인터페이스 상수 필드는 static {} 블록으로 초기화할 수 없기 대문에 반드시 선언과 동시에 초기값을 지정해야 합니다.
- public static final을 생략하더라도 자동적으로 컴파일 과정에서 붙게 됩니다.
추상 메소드 (Abstract Method)
[public abstract] 리턴타입 메소드명(매개변수, ...);
- 추상 메소드는 리턴타입, 메소드명, 매개 변수만 기술되고 중괄호 {}를 붙이지 않는 메소드입니다.
- 구현 클래스에서 구현해야 하는 메소드입니다.
- public abstract 선언 생략하더라도 자동적으로 컴파일 과정에서 붙게 됩니다.
디폴트 메소드 (Default Method)
[public] default 리턴타입 메소드명(매개변수, ...) {
// ... (실행 내용)
}
- 자바 8에서 추가된 인터페이스의 새로운 멤버
- default 키워드가 리턴 타입 앞에 붙습니다.
- 디폴트 메소드는 인스턴스 메소드이므로 구현 객체가 있어야 사용할 수 있습니다.
- 디폴트 메소드는 인터페이스의 모든 구현 객체가 가지고 있는 기본 메소드
- 구현 클래스 작성 시 디폴트 메소드를 오버라이딩해서 해당 구현 클래스에 맞게 수정할 수 있습니다.
- 디폴트 메소드는 public 특성을 갖기 때문에 public을 생략하더라도 자동적으로 컴파일 과정에서 붙게 됩니다.
정적 메소드 (Static Method)
[public] static 리턴타입 메소드명(매개변수, ...) {
// ... (실행 내용)
}
- 자바 8에서 추가된 인터페이스의 새로운 멤버
- static 키워드가 리턴 타입 앞에 붙습니다.
- 객체가 없어도 인터페이스만으로 호출이 가능합니다.
- 정적 메소드는 public 특성을 갖기 때문에 public을 생략하더라도 자동적으로 컴파일 과정에서 붙게 됩니다.
4. 인터페이스 구현 (implement)
구현 클래스
public class 구현클래스명 implments 인터페이스명 {
// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
}
- implements 키워드
- 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
예시
인터페이스 A
public interface A {
// 상수
String interfaceName = "A";
// 추상 메소드
void printImplementClassName();
// 디폴트 메소드
default void printHello() {
System.out.println("Hello");
}
// 정적 메소드
static void printInterfaceName() {
System.out.println(interfaceName);
}
}
인터페이스 A의 구현 클래스 AImpl
public class AImpl implements A {
@Override
public void printImplementClassName() {
System.out.println("AImpl");
}
// 디폴트 메소드를 오버라이딩 할 수도 있습니다.
// @Override
// public void printHello() {
// System.out.println("안녕하세요!");
// }
}
실행
// 정적 메소드 사용
A.printInterfaceName(); // A
// 구현 객체 생성
A a = new AImpl();
// 디폴트 메소드 사용
a.printHello(); // Hello
// 추상 메소드 사용
a.printImplementClassName(); // AImpl
다중 인터페이스 구현 클래스
- 다중 인터페이스를 구현할 경우, 구현 클래스는 모든 인터페이스의 추상 메소드에 대해 실체 메소드를 작성해야 합니다.
- 만약 추상 메소드를 하나라도 구현하지 않을 경우 추상 클래스로 선언해야 합니다.
예시
인터페이스 OnEvent
public interface OnEvent {
void on();
}
인터페이스 OffEvent
public interface OffEvent {
void off();
}
인터페이스 OnEvent, OffEvent의 구현 클래스 MacBook
public class MacBook implements OnEvent, OffEvent {
@Override
public void on() {
System.out.println("Mac Book On");
}
@Override
public void off() {
System.out.println("Mac Book Off");
}
}
추상 메소드를 하나라도 구현하지 않을 경우 추상 클래스로 선언 필요 (주의)
public abstract class MacBook implements OnEvent, OffEvent {
@Override
public void on() {
System.out.println("Mac Book On");
}
}
'Backend > 객체 지향 프로그래밍' 카테고리의 다른 글
[Java] 인터페이스의 타입 변환과 다형성 (0) | 2022.04.24 |
---|---|
[Java] 인터페이스 익명 구현 객체 (0) | 2022.04.23 |
[Java] 객체의 다형성 구현 (추상 클래스) (0) | 2022.04.20 |
[Java] 상속과 다형성 (Polymorphism) (0) | 2022.04.19 |
[Java] final 클래스 final 메소드 (0) | 2022.04.18 |