CodeGym /مدونة جافا /Random-AR /فئات مجهولة
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 كائنات واستدعاء طريقة واحدة عليها.

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