인터페이스의 요소
- 인터페이스도 다른 클래스와 같이 멤버를 가질 수 있습니다.
- 단, 인터페이스는 일종의 추상 클래스이기 때문에 스스로 인스턴스를 생성할 수 없습니다.
- 따라서 인스턴스를 생성하지 않아도 사용할 수 있는 요소들만 멤버로 가질 수 있습니다.
- 인터페이스의 멤버가 될 수 있는 요소는 아래와 같습니다.
- 상수 필드
- 추상 메서드
- 기본(디폴트) 메서드
- 정적 메서드
- (private) 메서드
- (private) 정적 메서드
상수 필드(Constant Field)
- 인터페이스는 public static final 특성을 갖는 불변의 상수 필드를 멤버로 가질 수 있습니다.
- 인터페이스에서 선언된 필드는 public static final 키워드를 생략해도 컴파일러가 자동으로 붙여줍니다.
- 상수는 구현하지 않아도 사용가능하기 때문에 인터페이스를 통해 바로 접근하여 사용할 수 있습니다.
- 상수 이름은 대문자로 붙이는 것이 관례이며 연결된 단어가 있을 경우 언더바(_)를 이용합니다.
상수 필드 사용 예시
public interface WalkSpeed {
// public static final은 입력하지 않아도 컴파일러가 자동으로 추가
public static final int MAX_SPEED = 10;
public static final int MIN_SPEED = 0;
}
추상 메서드(Abstract Method)
- 인터페이스는 구현 클래스가 재정의해야하는 public 추상 메서드를 가질 수 있습니다.
- 인터페이스에서 선언된 메서드는 public abstract를 생략하더라도 컴파일러가 자동으로 붙여줍니다.
- 인터페이스에 정의되는 추상 메서드는 모두 public의 접근 제한자를 가집니다.
- 인터페이스를 구현하는 클래스에서 해당 추상 메서드의 공개 범위를 더 낮은 접근 제어자로 재정의할 수 없습니다.
- 때문에 재정의되는 메서드는 모두 public의 접근 제한자를 가지게 됩니다.
- 추상 메서드는 인터페이스를 구현하는 클래스에서 구체화를 해야하며, 인터페이스형 변수를 통해 호출할 수 있습니다.
- 이 경우 변수에 대입시키는 구현 클래스에 따라 사용할 메서드가 바뀌기 때문에 목적에 맞춰 유연하게 조정할 수 있습니다.
- 이 경우 변수에 대입시키는 구현 클래스에 따라 사용할 메서드가 바뀌기 때문에 목적에 맞춰 유연하게 조정할 수 있습니다.
추상 메서드의 선언
public interface 인터페이스이름 {
[public abstract] 반환타입 메서드이름(매개변수, ...);
}
인터페이스 내 추상 메서드 활용 예시
// 인터페이스 선언
public interface Walkable {
// 추상 메서드 선언
// 걷기 시작하는 메서드
void startWalk();
// 멈추는 메서드
void stopWalk();
}
// 클래스 선언
public class Human implements Walkable {
// 필드 선언
private int walkSpeed;
// 인터페이스에 선언된 걷기 추상 메서드 구현
@Override
public void startWalk() {
System.out.println("사람이 걷기 시작합니다.");
}
// 인터페이스에 선언된 멈추기 추상 메서드 구현
@Override
public void stopWalk() {
System.out.println("걷기를 멈춥니다.");
}
}
기본 메서드(Default Method)
- 인터페이스는 실행부가 구현된 메서드를 가질 수 없어 구현 클래스에서 재정의하여 사용해야 합니다.
- 단, 자바8부터는 메서드를 디폴트로 선언한다면 실행부가 있는 메서드를 할 수 있습니다.
- 기본 메서드는 인터페이스의 선언부에 디폴트(default) 예약어를 붙여 생성할 수 있습니다.
- 기본 메서드를 인터페이스의 구현 클래스에서 재정의하여 사용할 수도 있습니다.
- 모든 구현 클래스에서 변경되지 않고, 공통으로 사용되는 메서드의 경우 기본 메서드로 구현할 경우 코드를 간소화 할 수 있습니다.
- 인터페이스의 경우 구현 클래스에서 여러 인터페이스를 다중으로 상속하는 것이 가능한데, 상속하는 인터페이스에 기본 메서드가 같은 이름으로 구현되어 있다면 컴파일 오류가 발생합니다.
- 이 경우 다중 상속으로 구현되는 클래스에서 해당 기본 메서드를 재정의해주어야 합니다.
- 이 경우 다중 상속으로 구현되는 클래스에서 해당 기본 메서드를 재정의해주어야 합니다.
기본 메서드 선언 방법
public interface 인터페이스이름 {
[public] default 리턴타입 메서드이름(매개변수, ...) {
기본 메서드 구현 내용
}
}
인터페이스 내 기본 메서드 활용 예시
// 인터페이스 선언
public interface Walkable {
public static final int MAX_SPEED = 10;
public static final int MIN_SPEED = 0;
void startWalk();
void stopWalk();
void setSpeed(int speed);
public default void forceStop(boolean danger) {
if(danger) {
System.out.println("강제로 정지합니다!");
setSpeed(MIN_SPEED);
}
else {
System.out.println("강제 정지를 해제합니다.");
}
}
}
// 클래스 선언
public class Human implements Walkable {
// 필드 선언
private int speed;
// 인터페이스에 선언된 걷기 추상 메서드 구현
@Override
public void startWalk() {
System.out.println("사람이 걷기 시작합니다.");
}
// 인터페이스에 선언된 멈추기 추상 메서드 구현
@Override
public void stopWalk() {
System.out.println("걷기를 멈춥니다.");
}
@Override
public setSpeed(int speed) {
if(speed > Walkable.MAX_SPEED) {
this.speed = Walkable.MAX_SPPED;
}
else if(speed < Walkable.MIN_SPEED) {
this.speed = Walkable.MIN_SPEED;
}
else {
this.speed = speed;
}
System.out.println("현재 속도는 " + speed + "입니다.");
}
}
정적 메서드(Static Method)
- 인터페이스는 정적 메서드 선언이 가능합니다.
- 인터페이스의 정적 메서드 선언 역시 일반 클래스의 정적 메서드 선언 방법과 동일합니다.
- 정적 메서드는 구현 객체가 없어도 사용할 수 있기 때문에, 인터페이스를 통해 바로 사용할 수 있습니다.
- 정적 메서드는 반드시 public 접근제어자로 선언해야 하며, 없다면 컴파일러가 자동으로 생성해줍니다.
private으로 선언된 메서드
- 인터페이스는 외부에서 접근할 수 없는 private 메서드를 선언할 수 있습니다.
- private 메서드는 기본 메서드와 정적 메서드의 중복된 코드를 줄이기 위해서 사용됩니다.
- private 메서드는 static으로 선언되는지의 여부에 따라서 사용 용도가 변할 수 있습니다.
- private 메서드: 구현 클래스가 필요하며, 기본 메서드 안에서만 호출이 가능합니다.
- private static 메서드: 구현 클래스가 필요하지 않아 기본 메서드는 물론 정적 메서드 안에서도 호출이 가능합니다.
인터페이스 내 private 메서드 사용 예시
public interface privateMethodExample {
// 기본 메서드1
default void defaultMethod1() {
System.out.println("기본 메서드1 실행");
// 반복 수행되는 기본 메서드
defaultCommonMethod();
}
// 기본 메서드2
default void defaultMethod2() {
System.out.println("기본 메서드2 실행");
// 반복 수행되는 기본 메서드
defaultCommonMethod();
}
// 정적 메서드1
static void staticMethod1() {
System.out.println("정적 메서드1 실행");
// 반복 수행되는 정적 메서드
staticCommonMethod();
}
// 정적 메서드2
static void staticMethod2() {
System.out.println("정적 메서드2 실행");
// 반복 수행되는 정적 메서드
staticCommonMethod();
}
// 기본 메서드에 포함되는 private 메서드
// 중복되는 코드를 따로 분리하여 별도 메서드화
private void defaultCommonMethod() {
System.out.println("중복되는 기본 메서드 로직");
}
// 정적 메서드에 포함되는 private 메서드
// 중복되는 코드를 따로 분리하여 별도 메서드화
private static void staticCommonMethod() {
System.out.println("중복되는 정적 메서드 로직");
}
}
'Programing Language > Java' 카테고리의 다른 글
[Java] 중첩 클래스의 분류(Separation of Nested Class) (0) | 2022.07.09 |
---|---|
[Java] 중첩 클래스(Nested Class) (0) | 2022.07.08 |
[Java] 인터페이스(Interface) (0) | 2022.07.06 |
[Java] 인터페이스의 상속 및 다형화(Interface Inheritance & Polymorphism) (0) | 2022.07.06 |
[Java] 추상 제어자와 추상 클래스(Abstract Modifier & Abstract Class) (0) | 2022.07.04 |