استخدام تعريفات الطبقة داخل الطريقة في جافا

StackOverflow https://stackoverflow.com/questions/2428186

  •  19-09-2019
  •  | 
  •  

سؤال

مثال:

public class TestClass {

    public static void main(String[] args) {
        TestClass t = new TestClass();
    }

    private static void testMethod() {
        abstract class TestMethod {
            int a;
            int b;
            int c;

            abstract void implementMe();
        }

        class DummyClass extends TestMethod {
            void implementMe() {}
        }

        DummyClass dummy = new DummyClass();
    }
}

اكتشفت أن القطعة المذكورة أعلاه قانونية تماما في جافا. لديك على الأسئلة التالية.

  1. ما هو استخدام تعريف فئة داخل الطريقة؟
  2. هل سيتم إنشاء ملف فئة ل DummyClass
  3. من الصعب بالنسبة لي أن أتخيل هذا المفهوم بطريقة موجهة للكائنات. وجود تعريف فئة داخل السلوك. ربما يمكن لأي شخص أن يقول لي مع أمثلة العالم الحقيقي المكافئ.
  4. فصول مجردة داخل الأسلوب تبدو مجنون بعض الشيء بالنسبة لي. ولكن لا توجد واجهات مسموح بها. هل هناك أي سبب وراء هذا؟
هل كانت مفيدة؟

المحلول

وهذا ما يسمى الطبقة المحلية.

2 هو السهل: نعم، سيتم إنشاء ملف فئة.

1 و 3 نوع من نفس السؤال. ستستخدم فئة محلية حيث لا تحتاج أبدا إلى إنشاء مثيل واحد أو معرفة تفاصيل التنفيذ في أي مكان ولكن بطريقة واحدة.

سيكون الاستخدام النموذجي لإنشاء تنفيذ رمي بعيدا لبعض الواجهة. على سبيل المثال، سترى غالبا شيئا مثل هذا:

  //within some method
  taskExecutor.execute( new Runnable() {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }); 

إذا كنت بحاجة إلى إنشاء مجموعة من هذه وتفعل شيئا معهم، فقد تغير هذا إلى

  //within some method
  class myFirstRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }
  class mySecondRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomethingElse( parameter );
       }
  }
  taskExecutor.execute(new myFirstRunnableClass());
  taskExecutor.execute(new mySecondRunnableClass());

فيما يتعلق بالواجهات: لست متأكدا مما إذا كانت هناك مشكلة فنية تجعل واجهات محددة محلية مشكلة للمترجم، ولكن حتى لو لم يكن هناك، فلن يضيف أي قيمة. إذا تم استخدام فئة محلية تنفذ واجهة محلية خارج الطريقة، فإن الواجهة ستكون بلا معنى. وإذا كان سيتم استخدام فئة محلية فقط داخل الطريقة، فسيتم تنفيذ كل من الواجهة والفئة داخل هذه الطريقة، لذلك سيكون تعريف الواجهة زائدة عن الحاجة.

نصائح أخرى

هذه تسمى الطبقات المحلية. وبعد يمكنك العثور على شرح مفصل ومثال هنا. وبعد المثال إرجاع تنفيذ معين لا نحتاج لمعرفته خارج الطريقة.

  1. لا يمكن رؤية الفئة (أي مثيل، وأساليبها التي يتم الوصول إليها دون انعكاس) من خارج الطريقة. أيضا، يمكنه الوصول إلى المتغيرات المحلية المحددة في TestMethod ()، ولكن قبل تعريف الفصل.

  2. اعتقدت فعلا: "لن يتم كتابة هذا الملف." حتى أنني جربت ذلك: أوه نعم، يتم إنشاء مثل هذا الملف! سيتم استدعاؤه بشيء مثل 1B.Class $، حيث تكون الطبقة الخارجية، و B هي الطبقة المحلية.

  3. خاصة بالنسبة لوظائف رد الاتصال (معالجات الأحداث في غياب، مثل OnClick () عند النقر فوق زر إلخ.)، من المعتاد استخدام "دروس مجهولة الهوية" - أولا وقبل كل شيء لأنه يمكنك أن ينتهي بكثير منهم. ولكن في بعض الأحيان تكون الطبقات المجهولة ليست جيدة بما فيه الكفاية - خاصة، لا يمكنك تحديد منشئ عليها. في هذه الحالات، يمكن أن تكون هذه الأسلوب الطبقات المحلية بديلا جيدا.

الغرض الحقيقي من ذلك هو السماح لنا بإنشاء فصول مضمنة في مكالمات الوظيفة إلى وحدة تحكم منا منا الذين يحبون التظاهر بأننا نكتب في لغة وظيفية؛)

الحالة الوحيدة عندما ترغب في الحصول على وظيفة فئة كاملة من الفئة الداخلية مقابل فئة مجهولة (AKA Java Linure) عندما يتم تلبية الشروط التالية

  1. تحتاج إلى توفير واجهة أو تنفيذ فئة مجردة
  2. تريد استخدام بعض المعلمات النهائية المحددة في وظيفة الاتصال
  3. تحتاج إلى تسجيل بعض حالة تنفيذ مكالمة الواجهة.

على سبيل المثال شخص ما يريد Runnable وتريد تسجيل عندما بدأ التنفيذ وانتهى.

مع فئة مجهولة، لا يمكن القيام به، مع الطبقة الداخلية التي يمكنك القيام بذلك.

هنا مثال على إظهار وجهة نظري

private static void testMethod (
        final Object param1,
        final Object param2
    )
{
    class RunnableWithStartAndEnd extends Runnable{
        Date start;
        Date end;

        public void run () {
            start = new Date( );
            try
            {
                evalParam1( param1 );
                evalParam2( param2 );
                ...
            }
            finally
            {
                end = new Date( );
            }
        }
    }

    final RunnableWithStartAndEnd runnable = new RunnableWithStartAndEnd( );

    final Thread thread = new Thread( runnable );
    thread.start( );
    thread.join( );

    System.out.println( runnable.start );
    System.out.println( runnable.end );
}

قبل استخدام هذا النمط، يرجى تقييم إذا كانت فئة المستوى الأعلى القديم العادي، أو الطبقة الداخلية، أو الطبقة الداخلية الثابتة هي بدائل أفضل.

السبب الرئيسي لتحديد الطبقات الداخلية (ضمن طريقة أو فئة) هو التعامل مع إمكانية الوصول إلى أعضاء ومتغيرات الفئة والطريقة المرفوعة. يمكن للفئة الداخلية البحث عن أعضاء البيانات الخاصة وتشغيلها عليها. إذا ضمن طريقة يمكن أن تتعامل مع المتغير المحلي النهائي أيضا.

إن وجود فصول داخلية تساعد في التأكد من أن هذه الفئة غير قابلة للوصول إلى العالم الخارجي. هذا يحمل صحيحا خاصة بالنسبة لحالات البرمجة UI في GWT أو GOTT، إلخ، حيث يتم كتابة رمز توليد JS في جافا والسلوك لكل زر أو حدث من خلال إنشاء فصول مجهولة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top