목표
자바의 인터페이스에 대해 학습.
목차
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
■ 완벽한 abstract 클래스는 interface
abstract class A {
public abstract void a();
public abstract String B();
}
위의 abstract 클래스를 아래와 같은 인터페이스로 정의할 수 있다.
interface A {
void a();
String B();
}
위의 인터페이스는 다음과 같은 특징을 지니는 특별한 클래스로 볼 수 있다.
일반적으로 클래스가 인터페이스를 상속하는 경우에는 '상속'이라는 표현을 하지 않고 '구현'이라는 표현을 쓴다. 하위클래스에서 인터페이스에 정의된 텅 빈 abstract 메서드를 구현해서 채워 넣어야 하기 때문이다.
그래서 인터페이스를 구현할 때에는 키워드 extends를 사용하지 않고 implements를 사용한다.
■ interface의 특성
public interface A {
public void methodA();
}
public interface B {
public void methodB();
}
위와 같은 두 개의 인터페이스가 정의되어 있을 때, 다음과 같이 클래스를 정의할 수 있다.
(인터페이스를 구현하는 클래스는 여러 개의 인터페이스를 동시에 구현할 수 있다.)
Class OurInterface implements A, B {
public void methodA();
public void methodB();
}
그리고 인터페이스간에도 extends 키워드로 상속관계를 형성할 수 있다.
■ 인터페이스 기반의 상수표현
public class Week {
public static final int MON=1;
public static final int TUE=2;
public static final int WED=3;
public static final int THU=4;
public static final int FRI=5;
public static final int SAT=6;
public static final int SUN=7;
}
인터페이스 내에 존재하는 변수는 무조건 public static final로 선언된다는 특성을 활용하여
아래와 같이 상수 기반 데이터로 이루어진 클래스를 단순화 시킬 수 있다.
public interface Week {
int MON=1, TURE=2, WED=3, THU=4, FRI=5, SAT=6, SUN=7;
}
인터페이스가 지니는 상수 선언의 장점이 있긴 하지만,
자바 버전 5.0 이후에는 열거형(enum)이라는 것이 제공되어 상수 선언이 필요한 일부 상황에서
인터페이스를 대체할 수 있다.
■ 클래스의 정의에, 약속된 형태의 특별한 표시를 위한 용도
어떤 문자를 출력하는 클래스가 있다고 가정할 때, UpperCasePrintable 이라는 인터페이스로 구현된 클래스에서는 대문자가 출력되고, 이것을 구현하지 않은 클래스는 원본 그대로 출력을 하는 기능으로 따로 나누고자 할 때도 인터페이스가 유용히 활용된다.
UpperCasePrintable 인터페이스를 정의한 후 비워놓고, instanceof 연산자를 통하여
클래스마다 기능을 나누면 된다.
이렇듯 인터페이스는 클래스의 정의에, 약속된 형태의 특별한 표시를 위한 용도로도 사용이 된다.
그리고 이러한 경우에는 아무것도 채워지지 않은 형태로 인터페이스가 정의되기도 한다.
상속 관계에 있는 클래스들 중에, 자손클래스의 인스턴스를 부모타입의 참조변수로 참조하는 것이 가능하다.
마찬가지로,
인터페이스도 이를 구현한 클래스의 부모라 할 수 있으므로 해당 인터페이스 타입의 참조변수로클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로 형변환도 가능하다.
interface A {
void interMethod() {}
}
class B implements A {
void intermethod() {
System.out.println("interMethod B");
}
}
class RefInterface {
public static void main(String[] args) {
A a = new B();
a.interMethod(); // interMethod B 출력
}
}
■ 인터페이스 - 인터페이스 간의 상속
인터페이스 끼리 상속을 받을 수 있다.
부모클래스와 자식클래스 간의 상속과 마찬가지로 extends 키워드를 사용한다.
■ 인터페이스 - 클래스 간의 상속
인터페이스를 상속한 클래스는 보통 "인터페이스를 구현한 클래스" 라는 표현을 사용한다.
implements 키워드를 사용하며, 다중상속이 가능하다.
예를 들어 인터페이스 A, B, C가 있고 클래스 D가 있다고 하면
C implmenets A, B, C {} 형식으로 사용한다.
■ 하위호환성의 문제를 보완한 인터페이스의 default method
인터페이스 내의 메서드는 반환형과 메서드 이름만 선언하고 바디부분에 기재하는 로직은 생략한다.
인터페이스를 구현할 클래스에서 로직을 구현하기 때문이다.
하지만 대규모로 이루어진 프로젝트에서, 인터페이스에 추가적으로 구현해야할 메서드가 생긴다면
이 인터페이스를 구현한 모든 클래스를 변경해야 하는 불상사가 발생할 수 있다.
즉 하위호환성에 문제가 생긴다는 것이다.
이러한 것을 보완하기 위해 인터페이스 내에서도 로직을 만드는 default method가 자바 8 부터 지원된다.
접근제어자에서 사용하는 default와 같은 키워드이지만, 접근제어자는 아무것도 명시하지 않은 접근제어자를 default라 하며
인터페이스의 default method는 'default'라는 키워드를 명시해야 한다.
interface에서도 메소드 구현이 가능하다.
참조 변수로 함수를 호출할 수 있다.
implements한 클래스에서 재정의가 가능하다.
자바 8 부터 인터페이스에 static 메소드 추가가 가능하다.
클래스에서와 동일한 방법으로 사용 가능하며 기본적으로 public으로 간주한다.
static 메소드 이므로 상속이 불가능 하다.
참고 서적 : 난 정말 JAVA를 공부한 적이 없어요 (ORANGE MEDIA 윤성우 저)