openplanning

Functional Interface trong Java

Xem thêm các chuyên mục:

Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

1- Functional Interface

Functional Interface là một khái niệm mới được đưa vào Java từ phiên bản 8, nó là một interface có duy nhất một phương thức trừu tượng. Các biểu thức Lambda thường được sử dụng để tạo nhanh một đối tượng của một Functional Interface.
Dưới đây là một Functional Interface, với một phương thức trừu tượng duy nhất:

package org.o7planning.ex;

public interface Greeting {

  String greeting(String name);
 
  default String hello(String name) {
      return "Hello " + name;
  }
}
Nếu một interface được thiết kế với mục đích là một functional interface bạn nên sử dụng annotation @FunctionalInterface để chú thích (anotate) cho nó, mặc dù điều này là không bắt buộc nhưng nó giúp những người khác dễ dàng hiểu được ý tưởng thiết kế của bạn, đồng thời nó cũng hỗ trợ trình biên dịch (compiler) thông báo các sai sót của bạn trong quá trình phát triển ứng dụng. Chẳng hạn trình biên dịch sẽ thông báo lỗi cho bạn nếu có một interface được chú thích bởi @FunctionalInterface nhưng có nhiều hơn một phương thức trừu tượng.

package org.o7planning.ex;

@FunctionalInterface
public interface Greeting {

  String greeting(String name);
 
  default String hello(String name) {
      return "Hello " + name;
  }
}
Tiếp tục với ví dụ trên. Trước Java 8, để sử tạo một đối tượng Greeting bạn phải tạo một lớp, sau đó implement phương thức trừu tượng của Greeting, điều này khá dài dòng.
UsingGreetingBeforeJ8.java

package org.o7planning.ex;

public class UsingGreetingBeforeJ8 {

    public static void main(String[] args) {
        
        // Create Greeting object:
        Greeting obj = new Greeting() {
            @Override
            public String greeting(String name) {
                return "Hi " + name;
            }
        };
        
        System.out.println(obj.greeting("Tran"));
        System.out.println(obj.hello("Tran"));
    }
}
Về cơ bản Functional Interface chỉ bao gồm 1 phương thức trừu tượng duy nhất, vì vậy bạn chỉ cần implement duy nhất phương thức này. Biểu thức Lambda của Java 8 giúp bạn viết lại ví dụ trên ngắn gọn hơn.
UsingGreetingJ8A.java

package org.o7planning.ex;

public class UsingGreetingJ8A {

    public static void main(String[] args) {
        
        // Create Greeting object with Lambda expression:
        Greeting obj = (String name) -> {
            return "Hi " + name;
        };
        
        System.out.println(obj.greeting("Tran"));
        System.out.println(obj.hello("Tran"));
    }
}
Các kiểu dữ liệu của các tham số trong phương thức trừu tượng của Greeting đều đã biết vì vậy không cần thiết phải viết lại chúng. Chúng ta có thể viết lại ví dụ trên ngắn gọn hơn:

Greeting obj = (name) -> {
    return "Hi " + name;
};
Nếu phương thức trừu tượng có duy nhất một tham số, bạn có thể không cần viết dấu ngặc đơn (parentheses) ( ) trong biểu thức Lambda:

Greeting obj = name -> {
    return "Hi " + name;
};
Nếu nội dung của phương thức chỉ bao gồm duy nhất một biểu thức bạn có thể không cần dấu ngặc nhọn (braces) { } và cũng không cần viết từ khoá "return".

Greeting obj = name ->  "Hi " + name;
Cuối cùng code của ví dụ trên đã ngắn hơn rất nhiều:
UsingGreetingJ8.java

package org.o7planning.ex;

public class UsingGreetingJ8 {

    public static void main(String[] args) {

        // Create Greeting object with Lambda expression:
        Greeting obj = name ->  "Hi " + name;

        System.out.println(obj.greeting("Tran"));
        System.out.println(obj.hello("Tran"));
    }
}
Output:

Hi Tran
Hello Tran

2- Examples

Tiếp theo chúng ta sẽ xem một vài Functional Interface bao gồm hợp lệ và không hợp lệ, và giải thích tại sao chúng không hợp lệ:
Interface IEquals dưới đây không phải là một functional interface vì phương thức "public boolean equals(Object)" là một thành viên được thừa kế từ lớp Object. Vì vậy IEquals được coi là không có phương thức trừu tượng nào và không đủ điều kiện để được coi là một functional interface.
IEquals.java (Invalid!)

package org.o7planning.j8fi;

@FunctionalInterface
public interface IEquals {
    
   boolean equals(Object other);
}
Hợp lệ:
IComparator.java (OK, Valid!)

package org.o7planning.j8fi;

@FunctionalInterface
public interface IComparator<T> {

    int compareTwoObject(T obj, T other);
    
    boolean equals(Object other);
}
Phương thức clone() của lớp Objectprotected (Không phải public). Vì vậy interface IWithClone dưới đây được coi là một functional interface hợp lệ.
IWithClone.java (OK, Valid)

package org.o7planning.j8fi;

@FunctionalInterface
public interface IWithClone {  
    
     Object clone();
}
Interface CC trong hình minh hoạ ở trên là một functional interface hợp lệ vì các phương thức trừu tượng mà nó được thừa kế từ AABB là giống nhau.

3- Các Functional Interface thông dụng

Dưới đây là vài functional interface thông dụng được sử dụng rộng rãi trong Java:

Xem thêm các chuyên mục: