반응형

 


 

메서드 참조란 말 그대로 다른 클래스의 메소드를 참조하여 사용한다입니다.

구현부를 빌려쓴다고 이해하시면 됩니다.

 

 

함수형 인터페이스가 클래스의 메서드 구현부를 빌려서 자신이 구현한 메서드인 것처럼 사용합니다.

 

 

람다식같은 경우는 직접 개발자가 구현부를 작성하는 것이고,

메서드 참조는 클래스를 빌려 쓰는 것입니다.

 

 

 

 

 

 

 

 

코드로 설명하겠습니다.

 


 

public class ProviderClass {
    public int providerFunc1(int x, int y){
        return x + y;
    }

    public int providerFunc2(int x, int y){
        return x - y;
    }

    public static int providerFunc3(int x, int y){
        return x * y;
    }

    public static int providerFunc4(int x, int y){
        return x / y;
    }
}

 

ProviderClass (메서드를 제공해줄 클래스)를 정의해두었습니다.

4개의 메소드를 정의해두었습니다.

 

3번 메소드, 4번 메서드는 static으로 선언해두었습니다.

 


 

@FunctionalInterface
public interface FuncInterface {
    public int shell(int x, int y);
}

 

메서드를 참조 사용하기 위해 껍데기 메서드가 있어야 합니다.

함수명 shell로 정의해두었습니다.

 

함수형 인터페이스 하나를 선언해두었습니다.

FuncInterface의 shell 메서드는 ProviderClass의 메서드의 구현부를 빌려서 사용할 겁니다.

 

껍데기 역할을 해줄 곳은 반드시 함수형 인터페이스여야 합니다.

함수형 인터페이스란 오로지 하나의 추상 메서드만을 갖고 있는 인터페이스를 말합니다.

 

하나의 추상 메서드만을 갖고 있어야 하는 이유는

여러 개의 추상 메서드를 갖고 있는 인터페이스가 다른 클래스의 메서드를 빌려 쓴다면,

타입의 혼란을 야기할 수 있기 때문에 반드시 하나의 추상 메서드만 있어야 합니다.

자바에서는 함수형 인터페이스가 아니면 메서드 참조를 할 수 없도록 막아둠

 

자바는 이러한 함수형 인터페이스를 제네릭으로 선언해 타입을 맞춰 API로 제공해줍니다.

java.util.function.*

 


 

public class mainClass {

    public static void main(String[] args) {

        // 메소드 제공 클래스
        ProviderClass providerClassInstance = new ProviderClass();

        // 제공받는 인터페이스
        FuncInterface funcInterface1 = providerClassInstance::providerFunc1; // 인스턴스 메소드는 "변수 명"으로 사용
        FuncInterface funcInterface2 = providerClassInstance::providerFunc2;
        FuncInterface funcInterface3 = ProviderClass::providerFunc3; // static 메소드는 "클래스 명"으로 사용
        FuncInterface funcInterface4 = ProviderClass::providerFunc4;

        // 참조하여 사용
        int sum = funcInterface1.shell(30,10); // 더하기
        int sub = funcInterface2.shell(30,10); // 빼기
        int mul = funcInterface3.shell(30,10); // 곱하기 (static)
        int div = funcInterface4.shell(30,10); // 나누기 (static)

        System.out.println(sum);
        System.out.println(sub);
        System.out.println(mul);
        System.out.println(div);
    }
}

 

인스턴스 메서드를 사용해야 할 때는

제공 클래스의 변수명::메서드명

 

클래스 메서드(static)를 사용할 때는

클래스 명::static 메서드 명

 

함수형 인터페이스 FuncInterface가 ProviderClass의 메서드들을 참조하면서

자신의 빈 껍데기 메서드 shell()로 ProviderClass에 구현된 메서드 기능을 참조하면서 자신의 것처럼 사용할 수 있습니다.

 

메서드를 참조하기 위해선 매개변수 타입, 리턴 타입, 개수가 일치해야 합니다.

 

 


 

메서드 참조: 함수형 인터페이스를 이용해서 다른 클래스의 메서드를 빌려쓰는 것

 


 

 

 

 

 

 

 

 

 

 

 

반응형
반응형

 

익명 클래스는 말 그대로 클래스의 이름이 없다.

익명 클래스는 설계도가 1회성이라는 말이다.

 

 

이름이 없으므로 생성자를 구현할 수 없다.

익명 클래스를 정의하려면 상속을 받거나 인터페이스로 구현해야한다.

 

 

참조 변수에 넣어두고 재사용할 수 있다.

상위 클래스의 생성자 지정, 오버 라이딩은 가능하다.

 

 

 


상속을 받은 익명 클래스

 

상속받아서 사용할 Outer 클래스

 

Outer 클래스를 익명 클래스로 활용

 

참조변수 o는 Outer를 상속받아서 1회성 구현부를 작성하고 인스턴스를 생성한 것과 같다.

 


인터페이스로 구현한 익명 클래스

 

 

추상메서드 2개를 갖는 인터페이스를 정의한 후

 

 

상속과 마찬가지로 인터페이스를 익명 클래스로 구현해서 사용할 수 있다.

 

참조변수 ti는 TestInterface의 추상메서드들을 구현하고 인스턴스를 생성한 것과 같다.

 

 


람다식(함수형 인터페이스)

 

위에서 본 익명클래스들의 생성을 코드 구현을 더 짧게 하고자 하는 것이 람다식이다.

 

마찬가지로 람다식은 단순히 함수를 구현하는 것 같지만 사실 객체의 생성이다.

인터페이스를 구현받아서 추상메서드를 작성하고 익명 객체를 생성한 것이다.

 

 

익명 클래스의 구현을 람다식으로 바꿔줄 수 있다.

(매개변수) -> 메서드 구현부

 

대신, 조건으로 인터페이스는 하나의 추상 메서드만을 갖고 있어야 한다.

하나의 추상 메서드만을 갖고 있는 인터페이스를 함수형 인터페이스라 한다.

 

람다식은 함수형 인터페이스를 이용해서 익명 객체로 구현하는 과정을 짧게 만든 것이다.

함수형 인터페이스가 갖고 있는 하나의 추상메서드의 1회성의 구현부를 만든 후 객체를 생성한 것

 

 


자바에는 이러한 함수형 인터페이스를 미리 만들어 둔 API가 있다.

https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/function/package-summary.html

 

java.util.function (Java SE 15 & JDK 15)

Functional interfaces provide target types for lambda expressions and method references. Each functional interface has a single abstract method, called the functional method for that functional interface, to which the lambda expression's parameter and retu

docs.oracle.com

 

 

 

 


 

반응형

+ Recent posts