JavaRush /Blog Java /Random-VI /Các lớp ẩn danh trong Java

Các lớp ẩn danh trong Java

Xuất bản trong nhóm
Xin chào! Trong bài học hôm nay chúng ta sẽ tiếp tục tìm hiểu về chủ đề các lớp lồng nhau. Đến lượt nhóm cuối cùng - các lớp bên trong ẩn danh trong Java. Hãy quay lại sơ đồ của chúng ta: Lớp học ẩn danh - 2Giống như các lớp cục bộ mà chúng ta đã nói đến trong bài giảng trước, các lớp ẩn danh là một tập hợp con của các lớp bên trong. Họ cũng có một số điểm tương đồng và khác biệt giữa chúng. Nhưng trước tiên, hãy tìm hiểu xem: tại sao họ thực sự được gọi là “ẩn danh”? Để làm điều này, chúng ta hãy xem một ví dụ đơn giản. Hãy tưởng tượng rằng chúng ta có một chương trình chính liên tục chạy và làm một việc gì đó. Chúng tôi muốn tạo một hệ thống giám sát cho chương trình này bao gồm một số mô-đun. Một mô-đun sẽ giám sát các chỉ số hiệu suất chung và ghi nhật ký, mô-đun thứ hai sẽ ghi lại và ghi lại các lỗi trong nhật ký lỗi, mô-đun thứ ba sẽ giám sát hoạt động đáng ngờ: ví dụ: các nỗ lực truy cập trái phép và những thứ khác liên quan đến bảo mật. Vì cả ba mô-đun về cơ bản chỉ bắt đầu ở phần đầu của chương trình và chạy ở chế độ nền, nên bạn nên tạo một giao diện chung cho chúng:
public interface MonitoringSystem {

   public void startMonitoring();
}
Nó sẽ được thực hiện bởi 3 lớp cụ thể:
public class GeneralIndicatorsMonitoringModule implements MonitoringSystem {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Security monitoring started!");
   }
}
Có vẻ như mọi thứ đều theo thứ tự. Chúng tôi có một hệ thống khá rõ ràng gồm một số mô-đun. Mỗi người trong số họ có hành vi riêng của mình. Nếu cần các mô-đun mới, chúng tôi có thể thêm chúng vì chúng tôi có giao diện khá dễ thực hiện. Nhưng hãy nghĩ xem hệ thống giám sát của chúng ta sẽ hoạt động như thế nào. Lớp học ẩn danh - 3Về cơ bản, chúng ta chỉ nên tạo 3 đối tượng - GeneralIndicatorsMonitoringModule, ErrorMonitoringModule, SecurityModule- và gọi một phương thức startMonitoring()trên mỗi đối tượng đó. Tức là tất cả những gì bạn cần làm là tạo 3 đối tượng và gọi 1 phương thức trên chúng.
public class Main {

   public static void main(String[] args) {

       GeneralIndicatorsMonitoringModule generalModule = new GeneralIndicatorsMonitoringModule();
       ErrorMonitoringModule errorModule = new ErrorMonitoringModule();
       SecurityModule securityModule = new SecurityModule();

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Đầu ra của bảng điều khiển:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Và đối với một công việc nhỏ như vậy, chúng tôi đã viết cả một hệ thống: 3 lớp và một giao diện! Và tất cả điều này chỉ vì 6 dòng mã. Mặt khác, lựa chọn của chúng tôi là gì? Vâng, thật không hay ho chút nào khi chúng tôi viết những lớp “dùng một lần” như vậy. Nhưng làm thế nào chúng ta có thể khắc phục điều này? Đây là nơi các lớp bên trong ẩn danh đến trợ giúp chúng tôi ! Đây là những gì chúng trông giống như trong trường hợp của chúng tôi:
public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Monitoring of general indicators has started!");
           }
       };



           MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Security monitoring started!");
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
Hãy cùng tìm hiểu chuyện gì đang xảy ra ở đây! Có vẻ như chúng ta đang tạo một đối tượng giao diện:
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }
};
Nhưng từ lâu chúng ta đã biết rằng không thể tạo ra các đối tượng giao diện! Đúng vậy, điều đó là không thể. Trên thực tế, chúng tôi không làm điều đó. Khoảnh khắc chúng tôi viết:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Bên trong máy Java, điều sau đây xảy ra:
  1. Một lớp Java chưa được đặt tên được tạo để triển khai MonitoringSystem.
  2. Trình biên dịch khi nhìn thấy một lớp như vậy sẽ yêu cầu bạn triển khai tất cả các phương thức giao diện MonitoringSystem(chúng tôi đã thực hiện việc này 3 lần).
  3. Một đối tượng của lớp này được tạo ra. Hãy chú ý đến mã:
MonitoringSystem generalModule = new MonitoringSystem() {

};
Có dấu chấm phẩy ở cuối! Cô ấy đứng đó là có lý do. Chúng ta đồng thời khai báo một lớp (thông qua dấu ngoặc nhọn) và tạo đối tượng của nó bằng cách sử dụng (); Mỗi đối tượng trong số ba đối tượng của chúng ta đã ghi đè một phương thức startMonitoring()theo cách riêng của nó. Cuối cùng, chúng tôi chỉ cần gọi phương thức này trên mỗi phương thức:
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
Đầu ra của bảng điều khiển:

Мониторинг общих показателей стартовал!
Мониторинг отслеживания ошибок стартовал!
Мониторинг безопасности стартовал!
Đó là tất cả! Chúng tôi đã hoàn thành nhiệm vụ của mình: chúng tôi đã tạo ba đối tượng MonitoringSystem, xác định lại nó theo ba cách khác nhau và gọi nó ba lần. Cả ba mô-đun đều được khởi chạy và hoạt động thành công. Đồng thời, cấu trúc chương trình của chúng tôi đã trở nên đơn giản hơn nhiều! GeneralIndicatorsMonitoringModuleCuối cùng , các lớp ErrorMonitoringModulebây giờ có thể SecurityModuleđược loại bỏ hoàn toàn khỏi chương trình! Đơn giản là chúng tôi không cần chúng - chúng tôi vẫn xoay sở tốt nếu không có chúng. Nếu mỗi lớp mô-đun ẩn danh của chúng tôi cần một số hành vi khác nhau, các phương thức cụ thể của riêng nó mà các lớp khác không có, chúng tôi có thể dễ dàng thêm chúng:
MonitoringSystem generalModule = new MonitoringSystem() {

   @Override
   public void startMonitoring() {
       System.out.println("Monitoring of general indicators has started!");
   }

   public void someSpecificMethod() {

       System.out.println("Specific method for first module only");
   }
};
Tài liệu của Oracle có một đề xuất hay : "Sử dụng các lớp ẩn danh nếu bạn cần một lớp cục bộ để sử dụng một lần." Một lớp ẩn danh là một lớp bên trong chính thức. Do đó, nó có quyền truy cập vào các biến lớp bên ngoài, bao gồm cả các biến tĩnh và riêng tư:
public class Main {

   private static int currentErrorsCount = 23;

   public static void main(String[] args) {

       MonitoringSystem errorModule = new MonitoringSystem() {

           @Override
           public void startMonitoring() {
               System.out.println("Bug Tracking Monitoring Started!");
           }

           public int getCurrentErrorsCount() {

               return currentErrorsCount;
           }
       };
   }
}
Chúng có điểm chung với các lớp cục bộ: chúng chỉ hiển thị bên trong phương thức mà chúng được định nghĩa. Trong ví dụ trên, mọi nỗ lực truy cập đối tượng errorModulebên ngoài phương thức main()sẽ không thành công. Và một hạn chế quan trọng hơn mà các lớp ẩn danh được kế thừa từ “tổ tiên” của chúng - các lớp bên trong: một lớp ẩn danh không thể chứa các biến và phương thức tĩnh . Nếu chúng ta cố gắng tạo phương thức getCurrentErrorsCount()từ ví dụ trên thành tĩnh, trình biên dịch sẽ báo lỗi:
//error! Inner classes cannot have static declarations
public static int getCurrentErrorsCount() {

   return currentErrorsCount;
}
Chúng tôi nhận được kết quả tương tự nếu chúng tôi cố gắng khai báo một biến tĩnh:
MonitoringSystem errorModule = new MonitoringSystem() {

   //error! Inner classes cannot have static declarations!
   static int staticInt = 10;

   @Override
   public void startMonitoring() {
       System.out.println("Bug Tracking Monitoring Started!");
   }

};
Cuối cùng, tôi có thể giới thiệu cho bạn một video xuất sắc về chủ đề lớp học ẩn danh, trong đó chủ đề này được giải thích đơn giản và rõ ràng nhất có thể :)
Và bài học hôm nay của chúng ta đã kết thúc! Và mặc dù chúng ta đã đề cập đến nhóm lớp lồng nhau cuối cùng, chúng ta vẫn chưa hoàn thành chủ đề này. Tiếp theo chúng ta sẽ học gì về các lớp lồng nhau? Bạn chắc chắn sẽ tìm ra sớm! :)
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION