# JAVA ## Interface *모든 메서드가 추창 메서드로 구현되어있는 클래스**즉 구현부가 있으면 안됨** ### Interface의 기능 *구현을 강제화 한다. *다형성을 제공한다. ```java interface MyRunnable { void myRun(); } interface YourRunnable { void yourRun(); } public class Main implements MyRunnable, YourRunnable { public static void main(String[] args) { Main m = new Main(); m.myRun(); m.yourRun(); MyRunnable myRunnable = new Main(); myRunnable.myRun(); YourRunnable yourRunnable = new Main(); yourRunnable.yourRun(); } @Override public void myRun() { System.out.println("Hello myRun!"); } @Override public void yourRun() { System.out.println("Hello yourRun!"); } } ``` *결합도를 낮춘다(로그인 인터페이스가 있고 / 네이버, 카카오 로그인 구현체가 있을 경우) >구체화에 의존하는 경우  >추상화에 의존하는 경우 >  ### default method 기능 *자바 8부터 인터페이스의 아쉬움이 있어서 강화되었다. *인터페이스가 구현체를 가질 수 있게 된 것입니다. ```java interface MyInterface { // 추상메서드로만 이뤄진 클래스 == 인터페이스 // 구현이 있다. // 추상메서드가 아니라는 얘기는 인터페이스 안에 구현체가 들어간다. default void sayHello() { System.out.println("Hello World"); } void method(); // 구현이 X } public class Main implements MyInterface{ public static void main(String[] args) { Main m = new Main(); m.sayHello(); } // 물론 오버라이드도 가능하다. @Override public void sayHello() { System.out.println("Bye World"); } @Override public void method() { throw new RuntimeException(); } } ``` *Adapter 역할을 하게 되었다. *인터페이스 추가만으로 기능을 확장할 수 있게 되었다. *static 메서드를 가질 수 있게 되었다. : 함수 제공자가 된다. *메서드는 클래스 안에 종속된 함수를 메서드라 부른다. 자바8 이상부터 함수형인터페이스가 생겨났다. ### Functional Interface ```java @FunctionalInterface interface MyMap { void map(); default void sayHello() { System.out.println("SayHello"); } static void sayBye() { System.out.println("ByeHello"); } } ``` *추상메서드가 하나만 존재하는 인터페이스 *default나 static은 상관없다. *@FunctionalInterface 애노테이션을 명시해줘야 한다. #### 인터페이스 임시 생성하기 *익명클래스를 사용하여 인터페이스 인스턴스를 생성하고 구현을 바로 정의하여 사용한다. ### Lambda 표현식 *메서드도 익명으로 만들 수 없을까?? *익명 메서드를 사용해서 간결한 인터페이스 인스턴스 생성 방법 ```java public class Main2 { public static void main(String[] args) { // 익명 클래스 사용 new MyRunnable() { @Override public void run() { System.out.println("hello"); } }.run(); // 익명메서드를 사용해서 표현하는 방식 : 람다 표현식 // 생략할 수 있게 만들어준다 어차피 오버라이드를 해줄것이기 때문이다. // 함수형 인터페이스라면 어차피 메서드는 하나이기 때문에 MyRunnable myRunnable = () -> System.out.println("hello"); } } ``` ***람다표현식은 함수형 인터페이스에서만 사용이 가능하다.**추상메서드가 하나일 경우엔 결국 구현할 메서드는 하나지만 두개 이상이 되버리면 어떤 메서드에 적용할 것인지 모르기 때문이다. *간결하게 표현이 가능하다. ```java MyMapper m = (str) -> str.length(); MyConsumer c = i -> System.out.println(i); ``` #### 메서드 레퍼런스 *입력되는 람다 표현식에서 입력되는 값을 변경없이 바로 사용하는 경우 *최종으로 적용될 메서드의 레퍼런스를 지정해 주는 표현방식 *값에 변형이 일어나면 사용하지 못함. ```java MyMapper m = String::length; MyConsumer c = System.out::println; ``` *메서드 레퍼런스를 사용하면 좋은 점은 들어오는 값을 변경하지 말고 그대로 사용한다는 의미를 가지게 된다. *개발자의 개입을 차단하며 안정성을 얻을 수 있다.