Trong Java 8 trở lên, câu trả lời cho câu hỏi này vẫn còn giá trị nhưng giờ đây đã có nhiều sắc thái hơn.
Đầu tiên, các câu sau từ câu trả lời được chấp nhận vẫn đúng:
- các giao diện có nghĩa là để chỉ định các hành vi ngầm của chúng trong một hợp đồng (một tuyên bố về các quy tắc cho hành vi mà các lớp triển khai phải tuân theo để được coi là hợp lệ)
- có sự khác biệt giữa hợp đồng (các quy tắc) và việc thực hiện (mã hóa theo chương trình của các quy tắc)
- các phương thức được chỉ định trong giao diện PHẢI LUÔN được triển khai (tại một số thời điểm)
Vậy, sắc thái mới trong Java 8 là gì? Khi nói về "Phương pháp tùy chọn", bất kỳ điều nào sau đây đều phù hợp:
1. Một phương pháp mà việc triển khai là tùy chọn theo hợp đồng
"Câu lệnh thứ ba" nói rằng các phương thức giao diện trừu tượng phải luôn được thực hiện và điều này vẫn đúng trong Java 8+. Tuy nhiên, như trong Java Collections Framework, có thể mô tả một số phương thức giao diện trừu tượng là "tùy chọn" trong hợp đồng.
Trong trường hợp này, tác giả đang triển khai giao diện có thể chọn không triển khai phương pháp. Tuy nhiên, trình biên dịch sẽ nhấn mạnh vào việc triển khai và do đó tác giả sử dụng mã này cho bất kỳ phương thức tùy chọn nào không cần thiết trong lớp triển khai cụ thể:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
Trong Java 7 trở về trước, đây thực sự là loại "phương thức tùy chọn" duy nhất có, tức là một phương thức, nếu không được triển khai, sẽ ném ra một ngoại lệ UnsupportedOperationException. Hành vi này nhất thiết phải được quy định bởi hợp đồng giao diện (ví dụ: các phương thức giao diện tùy chọn của Java Collections Framework).
2. Một phương pháp mặc định có việc triển khai lại là tùy chọn
Java 8 đã giới thiệu khái niệm về các phương thức mặc định . Đây là những phương thức mà việc triển khai có thể được và được cung cấp bởi chính định nghĩa giao diện. Nói chung, chỉ có thể cung cấp các phương thức mặc định khi thân phương thức có thể được viết bằng các phương thức giao diện khác (tức là "nguyên thủy") và khi nào this
có thể có nghĩa là "đối tượng này có lớp đã triển khai giao diện này."
Phương thức mặc định phải hoàn thành hợp đồng của giao diện (giống như bất kỳ phương thức triển khai phương thức giao diện nào khác). Do đó, việc chỉ định thực thi phương thức giao diện trong một lớp thực thi là tùy theo quyết định của tác giả (miễn là hành vi đó phù hợp với mục đích của họ).
Trong môi trường mới này, Java Collections Framework có thể được viết lại thành:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
Theo cách này, phương thức "tùy chọn" add()
có hành vi mặc định là ném một UnsupportedOperationException nếu lớp thực thi không cung cấp hành vi mới của riêng nó, đó là chính xác những gì bạn muốn xảy ra và tuân thủ hợp đồng cho Danh sách. Nếu tác giả đang viết một lớp không cho phép các phần tử mới được thêm vào triển khai Danh sách, thì việc triển khai add()
là tùy chọn vì hành vi mặc định là chính xác những gì cần thiết.
Trong trường hợp này, "câu lệnh thứ ba" ở trên vẫn đúng, vì phương thức đã được thực hiện trong chính giao diện.
3. Một phương thức trả về một Optional
kết quả
Loại phương thức tùy chọn mới cuối cùng chỉ đơn giản là một phương thức trả về một Optional
. Các Optional
lớp học cung cấp một cách hướng đối tượng decidedly hơn để đối phó với null
kết quả.
Trong một phong cách lập trình trôi chảy, chẳng hạn như kiểu thường thấy khi viết mã bằng Java Streams API mới, kết quả rỗng tại bất kỳ thời điểm nào khiến chương trình gặp sự cố với NullPointerException. Các Optional
lớp học cung cấp một cơ chế để trả kết quả null để mã khách hàng theo một cách mà cho phép phong cách thành thạo mà không gây ra mã khách hàng để sụp đổ.