Thiết kế interface luôn là một công việc khó khăn vì nếu chúng ta muốn thêm các phương thức bổ sung trong các interface, nó sẽ yêu cầu thay đổi trong tất cả các lớp thực thi. Khi interface cũ đi, số lượng các lớp triển khai nó có thể tăng đến mức không thể mở rộng interface. Đó là lý do tại sao khi thiết kế một ứng dụng, hầu hết các khung công tác đều cung cấp một lớp triển khai cơ sở và sau đó chúng tôi mở rộng nó và ghi đè các phương thức có thể áp dụng cho ứng dụng của chúng tôi.
Chúng ta hãy xem xét các phương thức default trong interface và phương thức static trong interface và lý do của việc giới thiệu chúng trong các thay đổi trong Java 8 interface.
Phương pháp default interface Java
Để tạo một phương thức default trong java interface, chúng ta cần sử dụng từ khóa “default” với chữ ký phương thức. Ví dụ:
package com.codetimes90.Java8.defaultmethod;
@FunctionalInterface
public interface Interface1
{
void method1(
String str);
default void log(String str) {
System.out.println("I1 logging: "+ str);
}
}
Lưu ý rằng log(String str) là phương thức default trong Interface1. Bây giờ khi một lớp sẽ triển khai Interface1, không bắt buộc phải cung cấp triển khai cho các phương thức default của interface. Tính năng này sẽ giúp chúng tôi mở rộng interface với các phương pháp bổ sung, tất cả những gì chúng tôi cần là cung cấp một triển khai default.
Giả sử chúng ta có một interface khác với các phương thức sau:
package com.codetimes90.Java8.defaultmethod;
@FunctionalInterface
public interface Interface2
{
void method2();
default void log(String str) {
System.out.println("I2 logging: "+ str);
}
}
Chúng tôi biết rằng Java không cho phép chúng tôi mở rộng nhiều lớp vì nó sẽ dẫn đến “Vấn đề kim cương” trong đó trình biên dịch không thể quyết định phương thức siêu lớp nào sẽ sử dụng. Với các phương pháp default, vấn đề kim cương cũng sẽ phát sinh đối với các interface. Bởi vì nếu một lớp đang triển khai cả Interface1 và Interface2 và không triển khai phương thức default chung, trình biên dịch không thể quyết định chọn phương thức nào.
Mở rộng nhiều interface là một phần không thể thiếu của Java, bạn sẽ tìm thấy nó trong các lớp java cốt lõi cũng như trong hầu hết các ứng dụng và khuôn khổ doanh nghiệp. Vì vậy, để đảm bảo, vấn đề này sẽ không xảy ra trong các interface, bắt buộc phải cung cấp triển khai cho các phương thức default phổ biến của interface. Vì vậy, nếu một lớp đang triển khai cả hai interface trên, nó sẽ phải cung cấp triển khai cho log() phương thức nếu không trình biên dịch sẽ ném ra lỗi compile-time.
Một lớp đơn giản đang triển khai cả hai Interface1 và Interface2 sẽ là:
package com.codetimes90.Java8.defaultmethod;
public class MyClass implements Interface1, Interface2 {
@Override
public void method2() {}
@Override
public void method1(String str) {}
@Override
public void log(String str){
System.out.println("MyClass logging::"+str);
Interface1.print("abc");
}
}
Các điểm quan trọng về các phương thức default của interface java:
Ø Các phương thức default của Java interface sẽ giúp chúng ta mở rộng interface mà không sợ phá vỡ các lớp thực thi.
Ø Các phương thức default của Java interface đã thu hẹp sự khác biệt giữa các interface và các lớp trừu tượng.
Ø Các phương thức default của Java 8 interface sẽ giúp chúng ta tránh các lớp tiện ích, chẳng hạn như tất cả các phương thức của lớp Collections có thể được cung cấp trong chính các interface.
Ø Các phương thức default của Java interface sẽ giúp chúng tôi loại bỏ các lớp triển khai cơ sở, chúng tôi có thể cung cấp triển khai default và các lớp thực thi có thể chọn cái nào để ghi đè.
Ø Một trong những lý do chính để giới thiệu các phương thức default trong interface là để nâng cao API Collections trong Java 8 để hỗ trợ các biểu thức lambda.
Ø Nếu bất kỳ lớp nào trong hệ thống phân cấp có một phương thức có cùng chữ ký, thì các phương thức default trở nên không liên quan. Một phương thức default không thể ghi đè một phương thức từ java.lang.Object. Lý do rất đơn giản, đó là vì Object là lớp cơ sở cho tất cả các lớp java. Vì vậy, ngay cả khi chúng ta có các phương thức của lớp Đối tượng được định nghĩa là phương thức default trong các interface, nó sẽ vô dụng vì phương thức của lớp Đối tượng sẽ luôn được sử dụng. Đó là lý do tại sao để tránh nhầm lẫn, chúng ta không thể có các phương thức default ghi đè các phương thức của lớp Object.
Ø Các phương thức default của Java interface còn được gọi là Defender Methods hoặc Virtual extension methods.
Phương thức static của Java interface tương tự như phương thức default ngoại trừ việc chúng ta không thể ghi đè chúng trong các lớp thực thi. Tính năng này giúp chúng tôi tránh các kết quả không mong muốn trong trường hợp triển khai kém trong các lớp triển khai. Hãy xem xét điều này với một ví dụ đơn giản.
package com.codetimes90.Java8.staticMethod;
public interface MyData
{
default void print(String str) {
if (!isNull(str)) {
System.out.println("my data print: "+ str);
}
}
static boolean isNull(String str) {
System.out.println("check null");
return str==null?true:"".equals(str)?true:null;
}
}
package com.codetimes90.Java8.staticMethod;
public class MyDataImpl implements MyData{
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
check
null
Impl
Null Check
Impl Null Check
my data print:
Impl Null Check
boolean result
= MyData.isNull("abc");
Các điểm quan trọng về phương thức static trong interface java:
Ø Phương thức static của Java interface là một phần của interface, chúng ta không thể sử dụng nó cho các đối tượng lớp thực thi.
Ø Các phương thức static của Java interface rất tốt để cung cấp các phương thức tiện ích, ví dụ: kiểm tra rỗng, sắp xếp bộ sưu tập, v.v.
Ø Phương thức static của Java interface giúp chúng tôi cung cấp bảo mật bằng cách không cho phép các lớp thực thi ghi đè lên chúng.
Ø Chúng tôi không thể xác định phương thức static interface cho các phương thức của lớp Object, chúng tôi sẽ gặp lỗi trình biên dịch là “This static method cannot hide the instance method from Object”. Điều này là do nó không được phép trong java, vì Object là lớp cơ sở cho tất cả các lớp và chúng ta không thể có một phương thức static cấp lớp và một phương thức thể hiện khác có cùng chữ ký.
Ø Chúng ta có thể sử dụng các phương thức static của Java interface để loại bỏ các lớp tiện ích như Collection và di chuyển tất cả các phương thức static của nó sang interface tương ứng, điều này sẽ dễ tìm và sử dụng.
Java Functional Interfaces
Trước khi kết thúc bài viết, tôi muốn giới thiệu sơ qua về các Functional interface. Một interface với chính xác một phương thức trừu tượng được gọi là Functional Interface.
Một chú thích mới @FunctionInterface đã được giới thiệu để đánh dấu một interface là Functional Interface. Chú thích @FunctionInterface là một cơ sở để tránh tình cờ bổ sung các phương thức trừu tượng trong các Functional interface. Nó là tùy chọn nhưng thực hành tốt để sử dụng nó.
Các Functional interface được chờ đợi từ lâu và là tính năng được tìm kiếm nhiều của Java 8 vì nó cho phép chúng ta sử dụng các biểu thức lambda để khởi tạo chúng. Một gói mới java.util.function với nhiều interface chức năng được thêm vào để cung cấp các kiểu đích cho các biểu thức lambda và các tham chiếu phương thức. Chúng tôi sẽ xem xét các Functional interface và biểu thức lambda trong các bài viết trong tương lai.

0 Nhận xét