자바의 인터페이스에 대해 학습하세요.
- 인터페이스 정의하는 방법
- 인터페이스 구현하는 방법
- 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
- 인터페이스 상속
- 인터페이스의 기본 메소드 (Default Method), 자바 8
- 인터페이스의 static 메소드, 자바 8
- 인터페이스의 private 메소드, 자바 9
인터페이스
public abstract
만 가능, Java8
이후 default method
, static method
, private method
가 가능인터페이스를 사용하는 이유
인터페이스 정의
// 접근제어자는 public 또는 default
(접근제어자) interface 인터페이스명 extends 인터페이스명1, 인터페이스명2 {
// public static final는 생략 가능
public static final (타입) 상수 = 값; // 상수명은 대문자로 표현
// public abstract 생략 가능
public abstract (타입) 추상메소드명(매개변수...); //
/***************** [JAVA 8 이후] *****************/
// 추상 메소드가 아닌 구현체를 포함한 메소드
// 추상 메소드가 아니더라도 구상 클래스에서 오버라이딩 할 수 있음
(public) default (타입) 디폴트메소드명(매개변수...) { ... } // public은 생략됨
// 구상클래스에서 오버라이딩 할 수 없음
(public) static (타입) 정적메소드명(매개변수...) { ... } // public은 생략됨
/***************** [JAVA 9 이후] *****************/
// 디폴트 메소드의 로직을 구현하기 위한 내부 메소드
private (타입) 메소드명(매개변수...) { ... }
// 정적 메소드의 로직를 구현하기 위한 내부 메소드
private static (타입) 메소드명(매개변수...) { ... }
}
인터페이스를 이용한 전역상수, 전역 정적메소드 선언하기
interface Friend {
String NAME = "manu"; // public static final 생략되어 있음
String AGE = "16"; // public static final 생략되어 있음
static String info() {
System.out.println(NAME + ", " + AGE);
}
}
...
Friend.NAME // == "manu"
Friend.AGE // == 16
Friend.info() // == "manu, 16"
구상 클래스를 이용하여 구현
/***************************[Pet.java]***************************/
public interface Pet {
void beFriendly();
void play();
}
/***************************[Dog.java]***************************/
public class Dog extends Canine implements Pet {
@Override
public void roam() { ... }
@Override
public void eat() { ... }
@Override
public void beFriendly() { ... }
@Override
public void play() { ... }
}
익명 구현 객체를 이용하여 구현
String sound = "멍멍~!"
String food = "뼈다귀"
Pet pet = new Pet() {
@Override
public void roam() {
System.out.println(sound);
}
@Override
public void eat() {
System.out.println(food);
}
}; // expression의 일종으므로 끝에 세미클론 붙여야 됨
Pet pet = new Dog();
// Pet 인터페이스의 메소드만 사용할 수 있음
pet.beFrendly();
pet.play();
// Dog 클래스에 roam(), eat() 메소드가 있지만 Pet 인터페이스로 참조했기 때문에 사용할 수 없음
pet.roam(); // error
pet.eat(); // error
extends
키워드 사용implements
키워드 사용인터페이스는 다중상속이 가능한 이유
기존 인터페이스에서 새로운 메소드를 추가하면 해줘야 하는 작업
default
메소드을 추가하여 상속 받은 구상 클래스에서 재정의없이 바로 사용가능죽음의 다이아몬드
// 죽음의 다이아몬드 해결하기 위해 애매한 메소드를 명시적으로 재정의해줘야 함
/***************************[Pet.java]***************************/
public interface Pet {
void beFriendly();
default void play() {
System.out.println("play with pet");
}
}
/***************************[Friend.java]***************************/
public interface Friend {
void beFriendly();
default void play() {
System.out.println("play with friend");
}
}
/***************************[Dog.java]***************************/
public class Dog implements Pet, Friend {
@Override
public void beFriendly() { ... }
@Override
public void play() {
Pet.super.Play(); // 어떤 인터페이스의 메소드를 호출할지 모를때 명시적으로 재정의
Friend.super.Play(); // 명시적으로 재정의하지 않을 시 컴파일 에러 발생!!
}
}
static
메소드는 재정의할 수 없음default
메소드와 static
메소드 함에 따라 메소드 안의 중복적인 코드를 제거하고 캡슐화하기 위해 private
메소드 등장default
메소드와 static
메소드를 이용해서 중복적인 코드를 제거할 수 있지만 캡슐화되지 않아 외부에서 접근 가능하기 때문에 private
키워드로 보완출처:
https://www.notion.so/8-0cc8c251d5374ac882a4f22fa07c4e6a
https://wikidocs.net/217
https://dev-coco.tistory.com/13
https://k3068.tistory.com/34
https://www.notion.so/4b0cf3f6ff7549adb2951e27519fc0e6
https://github.com/jongnan/java-study-with-whiteship/blob/master/week8/week8.md