12/08/2018, 16:51

Sự tiến hóa của Interface trong Java kể từ JDK 1.7 và những phiên bản trước đó

Xin chào các bạn, ngày hôm nay chúng ta hãy cùng ôn lại một chút kiến thức và tìm hiểu lý do vì sao Oracle lại cung cấp những tính năng mới cho Interface như default method, static method, private method ở các phiên bản JDK >= 8 . Hy vọng rằng, bài viết của mình sẽ giúp cho các bạn ghi nhớ và dễ ...

Xin chào các bạn, ngày hôm nay chúng ta hãy cùng ôn lại một chút kiến thức và tìm hiểu lý do vì sao Oracle lại cung cấp những tính năng mới cho Interface như default method, static method, private method ở các phiên bản JDK >= 8 . Hy vọng rằng, bài viết của mình sẽ giúp cho các bạn ghi nhớ và dễ dàng ứng dụng những kiến thức mới của Java 8 và Java 9 (trong tương lai) vào công việc hàng ngày. Hãy mở đầu bài viết bằng một câu nhận định của Code Pumpkin:

Ai ai cũng biết con người tiến hóa từ loài vượn, nhưng liệu các Java Dev có biết interface đã phát triển như thế nào không?

1. Interface ở Java 7 và những phiên bản trở về trước

Ở Java 7 và những phiên bản cũ hơn, chỉ có duy nhất hai thành phần được phép xuất hiện trong interface, đó là:

  • Biến hằng số: Các biến được khai báo và khởi tạo trong interface sẽ tương đương với public static final như ở các class bình thường

  • Phương thức trừu tượng Ví dụ: Biến hằng số trong interface

    Phương thức trừu tượng trong interface

Ở những phiên bản này, interface không thể chứa những phương thức có body, tức những phương thức đã được implement. Để vừa có phương thức trừu tượng và phương thức có body, chúng ta chỉ có cách duy nhất là sử dụng abstract class.

2. Interface ở Java 8

Interface là một trong những sự thay đổi đáng chú ý mà Oracle đã đính kèm trong bản Java 8 ra mắt vào năm 2014. Theo đó, giờ đây interface đã có thể chứa thêm những phương thức có body nữa và chúng ta có thể lựa chọn liệu có override những phương thức đó ở những class con hay không bằng việc sử dụng default hay static method.

Vậy tại sao lại phải có default method nhỉ?

Giả sử bạn có một class UserStorageService implement những phương thức abstract ở trong Interface IStorageService như sau:

Đáng chú ý là UserStorageService không phải là class duy nhất implement Interface này, vì vậy sau một vài năm nếu bị yêu cầu phải thêm 2 phương thức mới nữa thì chuyện sẽ rất phức tạp. Nếu thêm hai phương thức abstract vào trong IStorageService thì toàn bộ class implement interface này sẽ bị lỗi, báo đỏ ngay tức khắc. Và như thế, default method đã ra đời, như một vị cứu tinh để giải quyết vấn đề mở rộng interface theo chiều tương thích ngược. Chúng ta có thể thêm default method cho interface như thế này: Điểm hay của của default method là loại phương thức này nếu thêm ở trong interface sẽ không làm xáo trộn hay ảnh hưởng gì đến code đã được implement của những class implement interface này. Trong nhiều tình huống, chúng ta còn có thể override lại default method để thực hiện những logic cụ thể.

Thế tại sao lại cần static method nếu chúng ta đã có default method rồi? Cũng giống như default method, static method trong interface cũng là loại phương thức có body, nhưng điểm khác biệt là chúng ta không thể override lại những phương thức này ở trong các class implements, hay nói cách khác chúng chỉ thuộc về interface thôi. Chẳng hạn, chúng ta có interface Vehicle sau:

public interface Vehicle {
    // regular / default interface methods
    static int getHorsePower(int rpm, int torque) {
        return (rpm * torque) / 5252;
    }
}

Khi sử dụng, chúng ta bắt buộc phải dùng như sau:

Vehicle.getHorsePower(2500, 480));

Như vậy, có thể thấ, trong Java 8, interface có thể có những thành phần sau:

  • Biến hằng số
  • Phương thức trừu tượng
  • Phương thức default
  • Phương thức static

Tuy nhiên, điểm chưa hoàn thiện của interface ở Java 8, đó là phiên bản này vẫn chưa cho phép sự xuất hiện của private method nhằm ngăn chặn việc lặp code và phơi những đoạn code không cần thiết ra ngoài, trong trường hợp chúng ta khai báo nhiều phương thức default và static với những đoạn code giống nhau.

Mặc dù không có phương thức private, nhưng trong Java 8 chúng ta vẫn có thể tránh được việc lặp code và đóng gói code bằng cách dưới đây:

Như chúng ta có thể thấy, phương thức private của inner class không thể được truy cập trực tiếp từ class hoặc interface ngoài mà nó chỉ được truy cập bằng class Hidden mà thôi.

3. Interface ở Java 9

Để giảm bớt sự nhọc nhằn và phức tạp cho việc thay thế phương thức private trong interface như đã mô tả ở trên, Oracle đã chính thức thêm vào phương thức private trong Java 9 (được release năm 2017). Như vậy, tổng thể, trong Java 9, interface có thể chứa 6 thành phần như sau:

  • Biến hằng số
  • Phương thức trừu tượng
  • Phương thức default
  • Phương thức static
  • Phương thức private
  • Phương thức private static

Tuy nhiên, khi sử dụng phương thức private trong interface, chúng ta cần phải để ý những điểm quan trọng sau:

  1. Không thể sử dụng kết hợp hai từ khóa private và abstract cùng một lúc, bởi cả hai đều mang ý nghĩa không liên quan đến nhau
  2. Phương thức private phải có body
  3. Hạn chế viết code trùng lặp, thay vào đó sử dụng method private
  4. Chỉ phơi những phương thức thích hợp ra ngoài

Reference: CodePumpkin

0