자바 - 디폴트 메소드, 스태틱 메소드

SeungTaek·2021년 8월 23일
0

자바(Java)

목록 보기
3/8
post-thumbnail

본 게시물은 스스로의 공부를 위한 글입니다.
틀린 내용이 있을 수 있습니다.

📒 기본 메소드 (Default Methods)

  • 인터페이스에 메소드 선언이 아니라 구현체를 제공하는 방법
public interface Foo{
    void printName();
    default void printNameUpper(){
        System.out.println(getName().toUpperCase());
    }
    String getName();
}


class MyClass implements Foo{
}


public class Main {
    public static void main(String[] args) {
       MyClass my=new MyClass();
       my.printNameUpper("hiE"); //구현하지 않아도 사용이 가능하다.
    }
}

Q) 왜 기본 메소드 기능이 필요할까?

A) 인터페이스에 기능을 추가하면, 모든 구현체에서 오버라이딩해야 하는 문제 발생. 즉, 해당 인터페이스를 구현한 클래스를 깨트리지 않고 새 기능을 추가할 수 있다.

  • 기본 메소드는 구현체가 모르게 추가된 기능으로 그만큼 리스크가 있다.
    • 컴파일 에러는 아니지만 구현체에 따라 런타임 에러가 발생할 수 있다.
    • 반드시 문서화 할 것. (@implSpec 자바독 태그 사용)
/**
 * @implSpec
 * 이 구현체는 문자열을 대문자로 바꿔 출력해준다.
 */
default void printNameUpper(){
	System.out.println(getName().toUpperCase());
}
  • 본인이 수정할 수 있는 인터페이스에만 기본 메소드를 제공할 수 있다.
  • 인터페이스를 상속받는 인터페이스에서 다시 추상 메소드로 변경할 수 있다. 또는 필요에 따라 재정의해서 사용할 수도 있다.
public interface Foo{
    default void printNameUpper(String name){
        System.out.println(name.toUpperCase());
    }
}



public interface Bar extends Foo{
	void printNameUpper(String name); //다시 추상 메소드로 변경 가능.
}



public class MyClass implements Foo{
    @Override
    public void printNameUpper(String name){
        System.out.println(name.toLowerCase()); //재정의 가능
    }
}
  • Diamond Problem
//Foo, Bar 둘다 default void printNameUpper()이 선언되어 있는 경우
//두 인터페이스 중 누구것을 사용해야하는지 모르기 때문에 오류가 발생한다.
public class Default implements Foo, Bar{..} 

📒 스태틱 메소드

  • 간단한 기능을 가지는 유틸리티 메소드를 제공할 때 인터페이스에 스태틱 메소드를 제공할 수 있다.
    • 사용시에는 인터페이스이름.메소드이름()
  • static 메소드는 구현부에서 오버라이딩 할 수 없다.
public interface Foo{
	static void printAnything(){
		System.out.println("Foo");
	}
}


public class App{
	public static void main(String[] args){
		Foo.printAnything(); //인터페이스를 바로 사용 가능
	}
}

📒 private 메서드

  • 자바9에서 추가된 기능이다.

  • 인터페이스 내부 메소드를 외부에서 접근하지 않게 하고 싶을 수 있다.

  • 예를 들면 default 메소드 내에서 사용되는 메소드에는 외부에서 접근하지 못하게 할 수 있다.

public interface Boo {

    //interface 내부 메소드
    //외부에선 사용, 오버라이딩 등의 접근 자체가 불가능.
    private String printHello(){ 
        return "Hello";
    }
    
    default void Hello(){
        System.out.println(printHello()+" user!");
    }
}

Reference

인프런 더 자바(백기선)

profile
I Think So!

0개의 댓글