(W1D3) 인터페이스 이야기

인터페이스의 기능

  1. 구현을 강제한다.
  2. 다형성을 제공한다.
  3. 결합도를 낮춘다. (의존성 역전)

default Method

  • Java 8부터 인터페이스가 구현체를 가질 수 있게 되었다.
  • 구현이 안되어 있는 메소드(구현부가 없는 메소드) -> 추상 메소드
  • 구현이 되어있는 메소드 -> default 메소드

    public interface Example {
    	// 추상 메소드
    	void hello();
    	
    // default 메소드
    // 메소드 앞에 default만 붙이면 된다.
    default void printHello() {
    		System.out.println("Hello");
    	}
    }
  • 기존에는

    • 원하는 메소드만 오버라이드해서 쓰고 싶을 때 Adapter 클래스를 만들어서 상속하여 원하는 메소드만 사용
    • Adapter에서 implements로 구현해놓으면 Adapter 클래스를 상속받고, 원하는 메소드만 사용할 수 있었다.
    • 길고 지저분한 코드(사용하지 않은 메소드들)가 남는다.
  • Adapter 역할을 하게 되었고, 원하는 메소드만 오버라이드해서 사용할 수 있게 되었다.
  • 인터페이스 추가만으로 기능을 확장할 수 있게 되었다.
  • 특정 기능을 수행할 수 있는 static 메소드를 만들 수 있고, 수행할 수 있게 되었다. (함수 제공자)

함수형 인터페이스

  • 추상메소드가 하나만 존재하는 인터페이스
  • @FunctionalInterface : 함수형 인터페이스임을 가리키는 어노테이션

    • 추상 메소드가 하나면 된다.
    • default 메소드, static 메소드와 상관없다.
@FunctionalInterface
interface MyMap {
	void map();
  default void sayHello() {
    System.out.println("Hello");
  }
  static void sayBye() {
    System.out.println("Bye World");
  }
}
  • 인터페이스를 사용할 떄는 클래스를 설계하고 implements하고 생성했어야 했다. (귀찮, 복잡)

    익명 클래스-인터페이스 임시 생성

    • 익명 클래스를 사용해서 인터페이스의 인스턴스를 생성하고 구현을 바로 정의한다.
    • 익명 클래스를 이용하면 클래스 선언과 인스턴스화를 동시에 할 수 있다.
    // 일반적인 클래스
    class xxxx implements MySupply {
    @Override
    public String supply() {
      return "HH";
    }
    }
    
    // 이름없는 클래스를 생성한다. => 익명 클래스
    new MySupply() {
    @Override
    public String supply() {
      return "Hello World";
    }
    }.supply();

람다 표현식

  • 익명 메소드도 만들 수 있지 않을까?

    Myrunnable r1 = new Myrunnable() {
    @Override
    public void run() {
      System.out.println("Hello");
    }
    }
    
    // 익명 메소드를 사용해서 표현 : 람다 표현식
    MyRunnable r2 = () -> System.out.println("Hello");
  • 익명 메소드를 사용해서 간결한 인터페이스 인스턴스를 생성한다.
  • FunctionalInterface에서 가능하다.
  • 간결한 표현이 가능하다.
  • FunctionalInterface에 있는 추상메소드를 함수라고 부른다.

메소드 레퍼런스

  • 람다 표현식에서 입력되는 값을 변경없이 바로 사용하는 경우
  • 최종으로 적용될 메소드의 레퍼런스를 지정해주는 표현 방식
  • 입력값을 변경하지 말라는 표현 방식
  • 개발자의 개입을 차단함으로써 안정성을 확보할 수 있다.

    타입을 바꾸고 싶다면? -> 제네릭 사용

    레퍼런스 타입만(Primitive type은 불가능) 제네릭에 사용할 수 있다.


Written by@Myunghwan
Nothing changes if nothing changes

GitHub