자바의 인터페이스에 대해 학습하세요.
인터페이스
interface
예약어 사용해 정의interface MyInterface{
// 상수
타입 상수명 = 값;
// 추상 메서드
리턴타입 메서드명(파라미터);
// 디폴트 메서드
default 리턴타입 메서드명(파라미터){
...
}
// 정적 메서드
static 리턴타입 메서드명(파라미터){
...
}
// 프라이빗 메서드
private 리턴타입 메서드명(파라미터){
...
}
}
public static final
을 입력하지 않아도 컴파일러가 자동으로 추가Constant Interface
라고 하는데, 이는 안티 패턴public abstract
를 생략시 컴파일러가 자동으로 추가default
, static
메서드와 java9에 추가된 private
메서드에 대해서는 각 파트 참고인터페이스가 추상클래스보다 추상적인데 추상클래스는 언제 사용?
public abstract class AbstractClass implements MyInterface{
private String message = "상태 존재 여부";
@Override
public void printMessage(){
sout(message);
}
public void setMessage(String message){
this.message = message;
}
}
함수형 인터페이스
implements
예약어 사용해 구현class 클래스명 implements 인터페이스명 {
... //인터페이스에 정의된 추상메서드 모두 Override
}
extends
상속과 달리 implements A, B, C
같은 식으로 여러 인터페이스 다중상속 가능// [자바 기본 복습 6]의 다이나믹 메서드 디스패치 (Dynamic Method Dispatch) 예시
public class DMD {
public static void main(String[] args) {
Shape triangle = new Triangle();
Shape square = new Square();
triangle.printInfo();
square.printInfo();
}
interface Shape {
public void printInfo();
}
static class Triangle implements Shape {
@Override
public void printInfo() {
System.out.println("Triangle");
}
}
static class Square implements Shape {
@Override
public void printInfo() {
System.out.println("Square");
}
}
}
/*
실행결과
Triangle
Square
*/
interface DiscountPolicy {
...
}
class FixedDiscountPolicy {
...
}
class RateDiscountPolicy {
...
}
public class OrderService {
DiscountPolicy = new RateDiscountPolicy();
...
}
결합도
느슨한 결합을 통해 추상화에 의존 가능
DiscountPolicy
에 해당 인터페이스를 구현한 클래스가 "어떤" 메시지에 응답 해야할지 정해져있다FixedDiscountPolicy
, RateDiscountPolicy
에는 메시지에 "어떻게" 응답할 것인지 내부적으로 구현돼있다OrderService
는 DiscountPolicy
가 응답할 책임이 있는 메시지를 보내며 이때 어떤 구현체가 메시지에 응답할지는 몰라도 된다(즉, 어떻게 처리할지는 몰라도 된다) 따라서 다형성을 활용한 느슨한 결합이 가능하다interface MyInterface1 {
...
}
interface MyInterface2{
...
}
interface MyMyInterface1 implements MyInterface1 {
...
}
interface MyMyInterface2 implements MyInterface1, MyInterface2 {
...
}
default
예약어를 사용해 구현부까지 인터페이스에서 작성 가능interface MyInterface {
default 리턴타입 메서드명(파라미터){
...
}
}
Object
클래스의 메서드는 기본 메서드로 제공 불가 (구현체에서 재정의)
기본 메서드 역시 구현체에서 재정의 가능
인터페이스의 메서드에 구현부를 왜 추가?
default
메서드가 있다면 하위 호환성 유지 가능두 인터페이스를 상속하는데 메서드 선언부가 같은 메서드가 있다면?
{Instance}.super.{method}
형식으로 메서드 호출 가능인스턴스 생성과 상관없이 독립적으로 사용할 수 있는 메서드
사용할 때는 인터페이스 이름으로 직접 참조
static 메서드는 오버라이드 불가
interface MyInterface1 {
static void method() {
System.out.println("static method");
}
}
interface MyInterface2 {
default void method() {
System.out.println("default method");
}
}
class MyClass implements MyInterface1, MyInterface2 {
@Override
public void method() {
System.out.println("default method override");
}
}
public class Test {
public static void main(String[] args) {
(new MyClass()).method(); // "default method override"
MyInterface1.method(); // "static method"
}
}
method()
interface MyInterface {
private void privateMethod() {
...
}
private static void privateStaticMethod() {
...
}
default void defaultMethod() {
privateStaticMethod();
privateMethod();
...
}
}
📑📌📜✏️