자바

TIL 20240611 default 메서드와 static 메서드

개발자 백구 블로그 2024. 6. 11. 15:07

보통 인터페이스는 규칙을 잡거나 서브의 플로우 로직을 잡는 데에 사용하고는 하는데,

인터페이스를 구현하는 클래스에서는 메서드를 모두 구현해야하기 때문에 인테페이스에 메서드를 추가할 때 문제가 발생한다. 즉, 메서드 하나를 추가하게 되면 해당 인터페이스를 구현하는 모든 클래스에서는 해당 메서드를 구현해줘야 한다...

 

그래서 이러한 문제를 해결하기 위해서 정적 메서드와 디폴트 메서드를 사용한다.

 

 

1. default 메서드

 

추상 메서드의 기본적인 구현을 제공하는 메서드로, 

메서드 앞에 default 키워드를 붙이며 블럭{ }이 존재해야한다. 

default 메서드 역시 접근 제어자가 public으로 생략이 가능하다.

추상 메서드가 아니기 때문에 인터페이스의 구현체들에서 필수로 재정의 할 필요는 없다.

 

public class Main implements A {

    @Override
    public void a() {
        System.out.println("A");
    }


    public static void main(String[] args) {
        Main main = new Main();
        main.a();

        // 디폴트 메서드 재정의 없이 바로 사용가능합니다.
        main.aa();
    }
}

interface A {
    void a();
    default void aa() {
        System.out.println("AA");
    }
}

 

default 메서드의 이점으로는,

  • 역호환성 유지: 기존 인터페이스를 확장하고 새로운 메소드를 추가할 때, 이미 해당 인터페이스를 구현한 클래스들은 새 메소드를 구현하지 않아도 된다. 이로써 기존 코드의 역호환성을 유지할 수 있다.
  • 기본 구현 제공: 인터페이스에서 기본 구현을 제공함으로써, 해당 인터페이스를 구현하는 클래스에서 모든 메소드를 재정의할 필요가 없게 되었다. 이는 코드를 더 간결하게 만들어주고 새로운 기능을 추가하기 쉽게 한다.
  • 다중 상속 문제 해결: 원래 Java는 다중 상속을 지원하지 않지만 default 메소드를 통해 인터페이스에서 다중 상속과 유사한 기능을 제공할 수 있게 되었다. 클래스는 여러 인터페이스를 구현하여 다양한 기능을 효과적으로 조합할 수 있다.
  • 라이브러리 확장성: Java 표준 라이브러리의 인터페이스도 default 메소드를 사용하여 새로운 기능을 추가하고, 기존 코드와의 호환성을 유지하면서 업데이트할 수 있다.

 

 

 

 

2. static 메서드

 

인터페이스에서 static 메서드 선언이 가능하다.
static의 특성 그대로 인터페이스의 static 메서드 또한 객체 없이 호출이 가능하고 선언하는 방법과 호출하는 방법은 클래스의 static 메서드와 동일하다. 접근 제어자를 생략하면 컴파일러가 public을 추가해준다.

 

public class Main implements A {

    @Override
    public void a() {
        System.out.println("A");
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.a();
        main.aa();
        System.out.println();

        // static 메서드 aaa() 호출
        A.aaa();
    }
}

interface A {
    void a();
    default void aa() {
        System.out.println("AA");
    }
    static void aaa() {
        System.out.println("static method");
    }
}

 

  • 정적 메서드는 메서드가 정의된 클래스에 속해 있는것으로 취급되고 객체를 생성하여 호출할 필요 없이 클래스명을 통해 참조하여 호출할 수 있다. ex) ClassName.methodName(args).
  • 같은 클래스를 통해 생성된 객체들간 같은 코드를 사용하는 것을 보장하기 위해 사용된다.
  • 정적 메소드는 오버라이드(Override)될 수 없다. 컴파일 과정에서 정적 바인딩(static binding)되어 메소드 타입이 정해진다.
    • 부모클래스, 자식클래스 간 같은 이름의 메소드를 정의할 순 있다. 하지만 Method Hiding으로 인해 항상 상위 클래스의 정적 메소드만 호출된다.

 

static 메서드는 메모리 측면에서 효율적이고 객체를 생성하지 않고 사용가능 하기 때문에 속도가 빠르다는 이점이 있다