Functional Interface trong Java 8

Trong bài trước, tôi đã giới thiệu với các bạn Interface trong Java 8 là Default method và Static method. Trong bài này, chúng ta tiếp tục tìm hiểu một khái niệm mới về Interface trong Java 8 là Functional Interface.

Trước khi tìm hiểu Functional Interface, chúng ta hãy cùng so sánh thế nào Lập trình hướng đối tượng (Object Oriented Programming – OOP) và Lập trình hướng chức năng (Functional Programming – FP) trong Java.

1. So sánh Object-Oriented Programming vs Functional Programming

Object-Oriented Programming (OOP) là một mô hình lập trình dựa trên khái niệm đối tượng (object), là kết hợp giữa data thể hiện dưới dạng các trường (field) hoặc thuộc tính (attribute) và code thể hiện dưới dạng thủ tục (procedure) hoặc phương thức (method).

Functional programming (FP) là một mô hình lập trình, một kiểu xây dựng cấu trúc và các phần tử của các chương trình, xử lý tính toán dựa trên các function và nó tránh thay đổi trạng thái, dữ liệu có thể thay đổi được (mutable data).

Trong một chương trình, có hai thành phần chính: dữ liệu và hành vi (behavior hoặc code). OOP nói rằng tập hợp dữ liệu và hành vi liên quan của nó thành một “đối tượng” giúp dễ hiểu hơn về cách thức hoạt động của một chương trình. FP nói rằng dữ liệu và hành vi là khác biệt rõ rệt và nên được giữ riêng biệt để rõ ràng.

Chi tiết các bạn có thể tham khảo thêm tại link sau:

2. Functional Interface là gì?

Java 8 gọi các Interface có duy nhất một method trừu tượng là các Functional Interface, nó cũng có thể được gọi là Single Abstract Method (SAM) một cụm từ đôi khi chúng ta bắt gặp.

Java 8 cũng giới thiệu một annotation mới là @FunctionalInterface. Nó có thể sử dụng cho mục đích bắt lỗi ở thời điểm biên dịch nếu vô tình thêm một method trừu tượng khác nữa vào interface có đánh dấu bởi annotation này mà vi phạm quy tắc của Functional Interface.

Lợi ích chính của functional interface là chúng ta có thể sử dụng Lambda Expression để tạo ra thể hiện (instance) cho interface đó.

3. Quy tắc khai báo Functional Interface

3.1. Một Functional Interface hợp lệ chỉ có duy nhất một method trừu tượng.

1
2
3
4
5
6
7
8
package com.maixuanviet.functional_interface;
 
@FunctionalInterface
public interface DemoFunctionalInterface {
 
    void doSomething();
 
}

Functional Interface bên dưới không hợp lệ vì không có bất kỳ phương thức trừu tượng nào.

1
2
3
4
5
6
7
package com.maixuanviet.functional_interface;
 
@FunctionalInterface
public interface DemoFunctionalInterface {
   
 
}

Functional Interface bên dưới cũng không hợp lệ vì có nhiều hơn một method trừu tượng.

3.2. Một Functional Interface có thể có các phương thức của lớp java.lang.Object.

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.maixuanviet.functional_interface;
 
@FunctionalInterface
public interface DemoFunctionalInterface2 {
 
    void doSomething();
 
    int hashCode();
 
    String toString();
 
    boolean equals(Object obj);
}

Functional Interface bên dưới cũng không hợp lệ, bởi vì nó chỉ khai báo các phương thức của lớp Java.lang.Object. Không có bất kỳ phương thức trừu tượng nào của riêng nó.

Functional Interface bên dưới cũng không hợp lệ, bởi vì phương thức clone() của lớp java.lang.Object có phạm truy cập là protected, trong khi tất cả các phương thức trừu tượng của interface đều là public abstract nên phưng thức clone() này không phải là override lại phương thức clone() của lớp Object. Do đó interface này được xem như khai báo 2 phương thức doSomething() và clone(), nên vi phạm nguyên tắc của Functional Interface.

3.3. Phương thức default and static không phá vỡ quy tắc của functional interface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.maixuanviet.functional_interface;
 
@FunctionalInterface
public interface DemoFunctionalInterface3 {
 
    void doSomething();
 
    default void defaultMethod1() {
 
    }
 
    default void defaultMethod2() {
 
    }
 
    static void staticMethod() {
 
    }
 
}

3.4. Một Functional Interface có thể mở rộng một Interface khác chỉ khi nó không có bất kỳ phương thức trừu tượng nào.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.maixuanviet.functional_interface;
 
interface BaseInterface1 {
    void base();
}
 
interface BaseInterface2 {
    void base();
}
 
@FunctionalInterface
public interface DemoFunctionalInterface4 extends BaseInterface1, BaseInterface2 {
 
}

Functional Interface bên dưới không hợp lệ vì có Interface con có một phương thức trừu tượng doSomething() của riêng nó và kế thừa 1 phương thức base() từ Interface Base.

4. Các Functional Interface đã được định nghĩa trong Java 8 – Java Predefined-Functional Interfaces

Java cung cấp các Functional Interface được định nghĩa trước để xử lý lập trình functional bằng cách sử dụng các lambda expression và method references. Bạn cũng có thể định nghĩa Functional Interface tùy chỉnh của riêng bạn.

Danh sách các Functional Interface được đặt trong gói java.util.function. Các bạn có thể tham khảo theo link sau: https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

Như vậy là chúng ta đã tìm hiểu xong một khái niệm mới trong Java 8 là Functional Interface. Trong các bài viết tiếp theo chúng ta sẽ cùng tìm hiểu một tính năng mới khác rất là hay trong Java 8 là Lambda Expression. Các bạn sẽ thấy được lợi ích và cách sử dụng của Lamda Expression và Functional Interface trong Java 8 như: FunctionPredicateConsumerConsumer, …

Hy vọng bài viết này giúp ích cho các bạn. Cảm ơn các bạn đã quan tâm và theo dõi bài viết. Hẹn gặp lại ở bài viết tiếp theo.4.6

2 Trackbacks / Pingbacks

  1. Consumer trong Java 8 - Blog của VietMX
  2. Supplier trong Java 8 - Blog của VietMX

Leave a Reply

Your email address will not be published.


*