CodeGym /בלוג Java /Random-HE /שיעורים אנונימיים
John Squirrels
רָמָה
San Francisco

שיעורים אנונימיים

פורסם בקבוצה
היי! בשיעור של היום, נמשיך לבחון את נושא השיעורים המקוננים. עכשיו הגיע הזמן לקבוצה האחרונה: כיתות פנימיות אנונימיות. נחזור לתרשים שלנו: שיעורים אנונימיים - 2כמו הכיתות המקומיות עליהן דיברנו בשיעור האחרון, גם כיתות אנונימיות הן מעין כיתות פנימיות... יש להן גם כמה קווי דמיון ושוני. אבל קודם כל, בואו נצלול פנימה: למה בדיוק קוראים להם "אנונימיים"? כדי לענות על זה, שקול דוגמה פשוטה. תארו לעצמכם שיש לנו תוכנית בסיסית שפועלת כל הזמן ועושה משהו. אנו רוצים ליצור מערכת ניטור עבור תוכנית זו, המורכבת ממספר מודולים. מודול אחד יעקוב אחר אינדיקטורים כלליים של ביצועים ויתחזק יומן. השני ירשום ויתעד שגיאות ביומן שגיאות. השלישית תעקוב אחר פעילות חשודה: למשל, ניסיונות גישה לא מורשית ודברים אחרים הקשורים לאבטחה. מכיוון שכל שלושת המודולים צריכים, בעצם, פשוט להתחיל בתחילת התוכנית ולרוץ ברקע, יהיה זה רעיון טוב ליצור עבורם ממשק משותף:
public interface MonitoringSystem {

   public void startMonitoring();
}
3 שיעורי בטון יישמו את זה:
public class GeneralIndicatorMonitoringModule implements MonitoringSystem {

@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
}


public class ErrorMonitoringModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor errors!");
   }
}


public class SecurityModule implements MonitoringSystem {

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor security!");
   }
}
נראה שהכל מסודר. יש לנו מערכת די קוהרנטית המורכבת מכמה מודולים. לכל אחד מהם התנהגות משלו. אם אנחנו צריכים מודולים חדשים, אנחנו יכולים להוסיף אותם, כי יש לנו ממשק די קל ליישום. אבל בואו נחשוב איך מערכת הניטור שלנו תעבוד. שיעורים אנונימיים - 3בעיקרון, אנחנו רק צריכים ליצור 3 אובייקטים - GeneralIndicatorMonitoringModule, ErrorMonitoringModule, SecurityModule- ולקרוא startMonitoring()לשיטה על כל אחד מהם. כלומר, כל מה שאנחנו צריכים לעשות זה ליצור 3 אובייקטים ולקרוא עליהם שיטה 1.
public class Main {

   public static void main(String[] args) {

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

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
פלט מסוף:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
ועם כל כך מעט עבודה, כתבנו את כל המערכת: 3 מחלקות וממשק אחד! וכל זה כדי להשיג 6 שורות קוד. מצד שני, מה האפשרויות שלנו? ובכן, זה לא מאוד מגניב שכתבנו את השיעורים ה"חד פעמיים" האלה. אבל איך אנחנו יכולים לתקן את זה? הנה כיתות פנימיות אנונימיות באות להציל אותנו! כך הם נראים במקרה שלנו:
public class Main {

   public static void main(String[] args) {

       MonitoringSystem generalModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor general indicators!");
           }
       };



MonitoringSystem errorModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor errors!");
           }
       };

       MonitoringSystem securityModule = new MonitoringSystem() {
           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor security!");
           }
       };

       generalModule.startMonitoring();
       errorModule.startMonitoring();
       securityModule.startMonitoring();
   }
}
בואו להבין מה קורה! זה נראה כאילו אנחנו יוצרים אובייקט ממשק:
MonitoringSystem generalModule = new MonitoringSystem() {

@Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }
};
אבל אנחנו כבר מזמן יודעים שאנחנו לא יכולים ליצור אובייקטי ממשק! וכך זה - זה בלתי אפשרי. למעשה, זה לא מה שאנחנו עושים. כשאנחנו כותבים:
MonitoringSystem generalModule = new MonitoringSystem() {

};
הדברים הבאים מתרחשים בתוך מכונת ה-Java:
  1. נוצרת מחלקת Java ללא שם המיישמת את MonitoringSystemהממשק.
  2. כשהקומפיילר רואה מחלקה כזו, זה מחייב אותך ליישם את כל השיטות של הממשק MonitoringSystem(עשינו את זה 3 פעמים).
  3. נוצר אובייקט אחד מהמחלקה הזו. שימו לב לקוד:
MonitoringSystem generalModule = new MonitoringSystem() {

};
יש נקודה-פסיק בסוף! זה שם מסיבה כלשהי. אנו מכריזים בו-זמנית על המחלקה (באמצעות סוגרים מסולסלים) ויוצרים מופע שלה (באמצעות ();). כל אחד משלושת האובייקטים שלנו עוקף את startMonitoring()השיטה בדרכו שלו. לבסוף, אנו פשוט קוראים לשיטה הזו על כל אחד מהם:
generalModule.startMonitoring();
errorModule.startMonitoring();
securityModule.startMonitoring();
פלט מסוף:

Starting to monitor general indicators! 
Starting to monitor errors! 
Starting to monitor security!
זהו זה! השגנו את המטרה שלנו: יצרנו שלושה MonitoringSystemאובייקטים, עקפנו שיטה בשלוש דרכים שונות, וקראנו לה שלוש פעמים. כל שלושת המודולים נקראו בהצלחה והם פועלים. יחד עם זאת, המבנה של התוכנית שלנו הפך להרבה יותר פשוט! אחרי הכל, כעת ניתן להסיר לחלוטין את ה- GeneralIndicatorMonitoringModule, ErrorMonitoringModule, ואת SecurityModuleהשיעורים מהתוכנית! אנחנו פשוט לא צריכים אותם - עשינו עבודה נהדרת בלעדיהם. אם כל אחת מהמעמדות האנונימיות שלנו זקוקה להתנהגות שונה, למשל שיטות ספציפיות משלה שאין לאחרות, נוכל להוסיף אותן בקלות:
MonitoringSystem generalModule = new MonitoringSystem() {

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor general indicators!");
   }

   public void someSpecificMethod() {

       System.out.println("Specific method only for the first module");
   }
};
התיעוד של Oracle מספק המלצה טובה : "השתמש ב[מחלקות אנונימיות] אם אתה צריך להשתמש במחלקה מקומית פעם אחת בלבד." כיתה אנונימית היא כיתה פנימית מן המניין. בהתאם, יש לו גישה למשתנים של המחלקה החיצונית, כולל משתנים סטטיים ומשתנים פרטיים:
public class Main {

   private static int currentErrorCount = 23;

   public static void main(String[] args) {

       MonitoringSystem errorModule = new MonitoringSystem() {

           @Override
           public void startMonitoring() {
               System.out.println("Starting to monitor errors!");
           }

           public int getCurrentErrorCount() {

               return currentErrorCount;
           }
       };
   }
}
יש להם משהו במשותף עם מחלקות מקומיות: הם גלויים רק בתוך השיטה שבה הם מוצהרים. בדוגמה למעלה, כל ניסיון לגשת לאובייקט errorModuleמחוץ לשיטה main()ייכשל. ויש עוד מגבלה חשובה שמחלקות אנונימיות יורשות מ"אבותיהם" (מחלקות פנימיות): מחלקה אנונימית אינה יכולה להכיל משתנים ושיטות סטטיות . בדוגמה למעלה, אם ננסה להפוך את getCurrentErrorCount()השיטה לסטטית, המהדר יפיק שגיאה:
// Error! Inner classes cannot have static declarations
public static int getCurrentErrorCount() {

   return currentErrorCount;
}
נקבל את אותה תוצאה אם ​​ננסה להכריז על משתנה סטטי:
MonitoringSystem errorModule = new MonitoringSystem() {

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

   @Override
   public void startMonitoring() {
       System.out.println("Starting to monitor errors!");
   }

};
והשיעור שלנו היום הגיע לסיומו! אבל למרות שחקרנו את הקבוצה האחרונה של כיתות מקוננות, עדיין לא סיימנו את הנושא הזה. מה עוד נלמד על כיתות מקוננות? בטוח תגלו בקרוב! :)
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION