Sự khác biệt giữa lớp Abstact và giao diện
- Các lớp trừu tượng so với các giao diện trong Java 8
- Sự khác biệt về khái niệm:
Các phương thức mặc định giao diện trong Java 8
- Phương pháp mặc định là gì?
- Đã giải quyết lỗi biên dịch phương thức ForEach bằng Phương thức mặc định
- Phương pháp mặc định và nhiều vấn đề mơ hồ kế thừa
- Điểm quan trọng về các phương thức mặc định của giao diện java:
Phương thức tĩnh giao diện Java
- Phương thức tĩnh Giao diện Java, ví dụ mã, phương thức tĩnh so với phương thức mặc định
- Điểm quan trọng về phương thức tĩnh giao diện java:
Giao diện chức năng Java
Các lớp trừu tượng so với các giao diện trong Java 8
Các thay đổi giao diện Java 8 bao gồm các phương thức tĩnh và các phương thức mặc định trong các giao diện. Trước Java 8, chúng ta chỉ có thể có các khai báo phương thức trong các giao diện. Nhưng từ Java 8, chúng ta có thể có các phương thức mặc định và phương thức tĩnh trong các giao diện.
Sau khi giới thiệu Phương thức mặc định, có vẻ như các giao diện và các lớp trừu tượng là như nhau. Tuy nhiên, chúng vẫn là khái niệm khác nhau trong Java 8.
Lớp trừu tượng có thể định nghĩa hàm tạo. Chúng có cấu trúc chặt chẽ hơn và có thể có một trạng thái liên quan đến chúng. Ngược lại, phương thức mặc định chỉ có thể được triển khai trong các điều khoản gọi các phương thức giao diện khác, không có tham chiếu đến trạng thái của một triển khai cụ thể. Do đó, cả hai sử dụng cho các mục đích khác nhau và lựa chọn giữa hai thực sự phụ thuộc vào bối cảnh kịch bản.
Sự khác biệt về khái niệm:
Các lớp trừu tượng có giá trị cho việc triển khai các giao diện của bộ xương (tức là một phần) nhưng không nên tồn tại nếu không có giao diện phù hợp.
Vì vậy, khi các lớp trừu tượng được giảm hiệu quả thành tầm nhìn thấp, việc triển khai các giao diện của bộ xương, các phương thức mặc định có thể loại bỏ điều này không? Quyết định: Không! Việc thực hiện các giao diện hầu như luôn đòi hỏi một số hoặc tất cả các công cụ xây dựng lớp mà các phương thức mặc định thiếu. Và nếu một số giao diện không, đó rõ ràng là một trường hợp đặc biệt, điều này sẽ không khiến bạn lạc lối.
Các phương thức mặc định giao diện trong Java 8
Java 8 giới thiệu tính năng mới của Phương thức mặc định , hay (Phương thức bảo vệ), cho phép nhà phát triển thêm các phương thức mới vào Giao diện mà không phá vỡ việc triển khai các Giao diện này. Nó cung cấp tính linh hoạt để cho phép Giao diện xác định việc triển khai sẽ sử dụng làm mặc định trong trường hợp Lớp cụ thể không cung cấp triển khai cho phương thức đó.
Hãy xem xét ví dụ nhỏ để hiểu cách thức hoạt động của nó:
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
Lớp sau sẽ biên dịch thành công trong Java JDK 8,
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
Nếu bạn tạo một phiên bản của OldInterfaceImpl:
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
Các phương thức mặc định không bao giờ là cuối cùng, không thể được đồng bộ hóa và không thể ghi đè các phương thức của Object. Chúng luôn được công khai, điều này hạn chế nghiêm trọng khả năng viết các phương pháp ngắn và có thể sử dụng lại.
Các phương thức mặc định có thể được cung cấp cho Giao diện mà không ảnh hưởng đến các Lớp triển khai vì nó bao gồm triển khai. Nếu mỗi phương thức được thêm vào trong Giao diện được xác định bằng triển khai thì không có Lớp triển khai nào bị ảnh hưởng. Một lớp triển khai có thể ghi đè lên việc thực hiện mặc định được cung cấp bởi Giao diện.
Các phương thức mặc định cho phép thêm chức năng mới vào các Giao diện hiện có mà không phá vỡ triển khai cũ của các Giao diện này.
Khi chúng tôi mở rộng giao diện chứa phương thức mặc định, chúng tôi có thể thực hiện như sau,
- Không ghi đè phương thức mặc định và sẽ kế thừa phương thức mặc định.
- Ghi đè phương thức mặc định tương tự như các phương thức khác mà chúng tôi ghi đè trong lớp con.
- Redeclare phương thức mặc định là trừu tượng, buộc lớp con ghi đè lên nó.
Đã giải quyết lỗi biên dịch phương thức ForEach bằng Phương thức mặc định
Đối với Java 8, các bộ sưu tập JDK đã được mở rộng và phương thức forEach được thêm vào toàn bộ bộ sưu tập (hoạt động cùng với lambdas). Với cách thông thường, mã trông như dưới đây,
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
Do kết quả này, mỗi Lớp triển khai có lỗi biên dịch, do đó, một phương thức mặc định được thêm vào bằng cách triển khai bắt buộc để thực hiện không nên thay đổi.
Giao diện lặp có thể lặp lại với phương thức Mặc định bên dưới,
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
Cơ chế tương tự đã được sử dụng để thêm Stream trong Giao diện JDK mà không phá vỡ các Class triển khai.
Phương pháp mặc định và nhiều vấn đề mơ hồ kế thừa
Do Lớp java có thể triển khai nhiều Giao diện và mỗi Giao diện có thể định nghĩa phương thức mặc định có cùng chữ ký phương thức, do đó, các phương thức được kế thừa có thể xung đột với nhau.
Xem xét ví dụ dưới đây,
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
Đoạn mã trên sẽ không biên dịch được với lỗi sau,
java: class Impl kế thừa các mặc định không liên quan cho defaultMethod () từ các loại InterfaceA và InterfaceB
Để sửa lỗi lớp này, chúng tôi cần cung cấp phương thức thực hiện mặc định:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
Hơn nữa, nếu chúng tôi muốn gọi triển khai mặc định được cung cấp bởi bất kỳ Giao diện siêu nào thay vì triển khai riêng của chúng tôi, chúng tôi có thể làm như sau,
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
Chúng tôi có thể chọn bất kỳ triển khai mặc định hoặc cả hai như là một phần của phương pháp mới của chúng tôi.
Điểm quan trọng về các phương thức mặc định của giao diện java:
- Các phương thức mặc định của giao diện Java sẽ giúp chúng tôi mở rộng các giao diện mà không sợ phá vỡ các lớp triển khai.
- Các phương thức mặc định của giao diện Java đã thu hẹp sự khác biệt giữa các giao diện và các lớp trừu tượng.
- Các phương thức mặc định của giao diện Java 8 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 lớp Bộ sưu tập có thể được cung cấp trong chính các giao diện.
- Các phương thức mặc định của giao diện Java sẽ giúp chúng ta loại bỏ các lớp triển khai cơ sở, chúng ta có thể cung cấp cài đặt mặc định và các lớp triển khai có thể chọn lớp nào để ghi đè.
- Một trong những lý do chính để giới thiệu các phương thức mặc định trong các giao diện là để tăng cường API Bộ sưu tập 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 mặc định trở nên không liên quan. Một phương thức mặc định 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 lớp Object được định nghĩa là các phương thức mặc định trong các giao diện, nó sẽ vô dụng vì phương thức lớp Object sẽ luôn được sử dụng. Đó là lý do để tránh nhầm lẫn, chúng ta không thể có các phương thức mặc định ghi đè các phương thức lớp Object.
- Các phương thức mặc định của giao diện Java cũng được gọi là Phương thức bảo vệ hoặc Phương thức mở rộng ảo.
Liên kết tài nguyên:
- Giao diện với các phương thức mặc định so với lớp Trừu tượng trong Java 8
- Lớp trừu tượng so với giao diện trong kỷ nguyên JDK 8
- Giao diện tiến hóa thông qua các phương thức mở rộng ảo
Phương thức tĩnh giao diện Java
Phương thức tĩnh Giao diện Java, ví dụ mã, phương thức tĩnh so với phương thức mặc định
Phương thức tĩnh giao diện Java tương tự như phương thức mặc định ngoại trừ việc chúng ta không thể ghi đè chúng trong các lớp triển khai. Tính năng này giúp chúng tôi tránh các kết quả không mong muốn khi thực hiện kém trong các lớp thực hiện. Hãy xem xét điều này với một ví dụ đơn giản.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
Bây giờ chúng ta hãy xem một lớp triển khai đang có phương thức isNull () với việc triển khai kém.
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");
}
}
Lưu ý rằng isNull (Chuỗi str) là một phương thức lớp đơn giản, nó không ghi đè phương thức giao diện. Ví dụ: nếu chúng ta sẽ thêm chú thích @Override vào phương thức isNull (), nó sẽ dẫn đến lỗi trình biên dịch.
Bây giờ khi chúng tôi sẽ chạy ứng dụng, chúng tôi nhận được đầu ra sau.
Kiểm tra Null giao diện
Impl Null Kiểm tra
Nếu chúng ta thực hiện phương thức giao diện từ tĩnh sang mặc định, chúng ta sẽ nhận được đầu ra sau.
Impl Null Kiểm tra
In MyData ::
Impl Null Kiểm tra
Phương thức tĩnh của giao diện Java chỉ hiển thị với các phương thức giao diện, nếu chúng ta loại bỏ phương thức isNull () khỏi lớp MyDataImpl, chúng ta sẽ không thể sử dụng nó cho đối tượng MyDataImpl. Tuy nhiên, giống như các phương thức tĩnh khác, chúng ta có thể sử dụng các phương thức tĩnh giao diện bằng cách sử dụng tên lớp. Ví dụ: một tuyên bố hợp lệ sẽ là:
boolean result = MyData.isNull("abc");
Điểm quan trọng về phương thức tĩnh giao diện java:
- Phương thức tĩnh của giao diện Java là một phần của giao diện, chúng ta không thể sử dụng nó cho các đối tượng lớp thực hiện.
- Các phương thức tĩnh của giao diện Java rất tốt để cung cấp các phương thức tiện ích, ví dụ kiểm tra null, sắp xếp bộ sưu tập, v.v.
- Phương thức tĩnh giao diện Java 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 hiện ghi đè lên chúng.
- Chúng ta không thể định nghĩa phương thức tĩnh giao diện cho các phương thức của lớp Object, chúng ta sẽ gặp lỗi trình biên dịch là vì Phương thức tĩnh này không thể ẩn phương thức cá thể khỏi Object. Điều này là do java 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 tĩnh cấp lớp và một phương thức cá thể khác có cùng chữ ký.
- Chúng ta có thể sử dụng các phương thức tĩnh của giao diện java để loại bỏ các lớp tiện ích như Bộ sưu tập và di chuyển tất cả các phương thức tĩnh của nó sang giao diện tương ứng, rất dễ tìm và sử dụng.
Giao diện chức năng Java
Trước khi kết thúc bài viết, tôi muốn giới thiệu ngắn gọn về các giao diện Chức năng. Một giao diện với chính xác một phương thức trừu tượng được gọi là Giao diện chức năng.
Một chú thích mới @FunctionalInterface
đã được giới thiệu để đánh dấu một giao diện là Giao diện chức năng.@FunctionalInterface
chú thích là một phương tiện để tránh vô tình bổ sung các phương thức trừu tượng trong các giao diện chức năng. Đó là tùy chọn nhưng thực hành tốt để sử dụng nó.
Các giao diện chức năng được chờ đợi từ lâu và tính năng được tìm kiếm nhiều của Java 8 vì nó cho phép chúng tôi sử dụng các biểu thức lambda để khởi tạo chúng. Một gói java.util.feft mới với một loạt các giao diện chức năng được thêm vào để cung cấp các loại mục tiêu 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 giao diện chức năng và biểu thức lambda trong các bài viết trong tương lai.
Vị trí tài nguyên:
- Thay đổi giao diện Java 8 - phương thức tĩnh, phương thức mặc định