لماذا يمكن لفئات Java الخارجية الوصول إلى أعضاء الطبقة الداخلية الخاصة؟

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

سؤال

لقد لاحظت أن الفئات الخارجية يمكنها الوصول إلى متغيرات المثيلات الخاصة للفئات الداخلية.كيف يكون هذا ممكنا؟إليك نموذج رمز يوضح نفس الشيء:

class ABC{
    class XYZ{
        private int x=10;
    }

    public static void main(String... args){
        ABC.XYZ xx = new ABC().new XYZ();
        System.out.println("Hello :: "+xx.x); ///Why is this allowed??
    }
}

لماذا يسمح بهذا السلوك؟

هل كانت مفيدة؟

المحلول

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

  1. ستكون بعض الوظائف في صفك الخارجي أكثر وضوحًا إذا تم تنفيذها في فصل منفصل.
  2. على الرغم من أنها تنتمي إلى فئة منفصلة، ​​إلا أن الوظيفة ترتبط ارتباطًا وثيقًا بالطريقة التي تعمل بها الطبقة الخارجية.

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

نصائح أخرى

إذا كنت ترغب في إخفاء أعضاء الخاص من الطبقة الداخلية الخاصة بك، يمكنك تحديد واجهة مع أعضاء العام وخلق طبقة داخلية مجهولة المصدر التي تطبق هذه الواجهة. مثال رفع الصوت عاليا:

class ABC{
    private interface MyInterface{
         void printInt();
    }

    private static MyInterface mMember = new MyInterface(){
        private int x=10;

        public void printInt(){
            System.out.println(String.valueOf(x));
        }
    };

    public static void main(String... args){
        System.out.println("Hello :: "+mMember.x); ///not allowed
        mMember.printInt(); // allowed
    }
}

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

والطريقة التي يتم تنفيذ ذلك هي استخدام أساليب محمي حزمة الاصطناعية: سيتم تجميع الطبقة الداخلية لفئة منفصلة في نفس الحزمة (ABC $ XYZ). وJVM لا يدعم هذا المستوى من العزلة مباشرة، بحيث على مستوى بايت كود ABC $ XYZ سيكون أساليب حماية الحزمة التي تستخدم الطبقة الخارجية للوصول الى طرق / مجالات خاصة.

هناك إجابة صحيحة تظهر على سؤال آخر مشابه لهذا:لماذا يمكن الوصول إلى العضو الخاص في فئة متداخلة من خلال أساليب الفئة المرفقة؟

تقول أن هناك تعريفًا للنطاق الخاص JLS - تحديد إمكانية الوصول:

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

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

في تناقض مع عنوان <لأ href = "https://stackoverflow.com/questions/1801718/outer-java-class-is-able-to-access-inner-class-private-members/1801925#1801925" = "abyx"> abyx معلنا الطبقة ثابت لا يتغير القيود المفروضة على الوصول إلى فئة إرفاق كما هو موضح أدناه. أيضا القيود المفروضة على الوصول بين الطبقات ثابتة في نفس الفئة إرفاق تعمل. فوجئت ...

class MyPrivates {
    static class Inner1 { private int test1 = 2; }
    static class Inner2 { private int test2 = new Inner1().test1; }

    public static void main(String[] args) {
        System.out.println("Inner : "+new Inner2().test2);
    }
}
تتم

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

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

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

إذا، في قضيتك، فإنه لا معنى للطبقات لتكون قادرة على مشاهدة الأعمال الداخلية بعضهم البعض - وهو ما يعني أساسا أن الطبقة الداخلية يمكن ببساطة بذلت فئة العادية، يمكنك تعريف الطبقة الداخلية كما static class XYZ . وسوف تستخدم static يعني أنها لن تشارك الدولة (وعلى سبيل المثال سوف new ABC().new XYZ() لا تعمل، وسوف تحتاج إلى استخدام new ABC.XYZ().
ولكن، إذا كان هذا هو الحال، يجب أن نفكر حول ما إذا كان XYZ ينبغي أن تكون حقا فئة الداخلية وأنه ربما يستحق ملف خاص به. أحيانا فمن المنطقي لإنشاء فئة الداخلية ثابتة (على سبيل المثال، إذا كنت في حاجة الى الطبقة الصغيرة التي تطبق واجهة الطبقة الخارجية الخاص بك يستخدم، وهذا لن يكون مفيدا في أي مكان آخر). ولكن في نصف حول من الوقت الذي كان ينبغي إجراء الطبقة الخارجية.

وأضاف تيلو على الإجابة للحصول على سؤالك الأول "كيف يكون هذا ممكنا؟". أود أن أتحدث قليلا على سؤال الثاني: لماذا هذا السلوك يسمح

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

وهكذا، لماذا بعد ذلك؟ أعتقد توضيح مثال نقطة أفضل.

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

ولذا، فإن الدماغ هو جزء لا يتجزأ من الجسم - والغريب، والعكس أيضا. عن طريق التحكم في الوصول بين هذه الكيانات ذات صلة وثيقة التنازل عن مطالبتهم العلاقة. إذا كنت بحاجة إلى التحكم في الوصول، ثم عليك أن تفصل بين الطبقات أكثر إلى وحدات متميزة حقا. حتى ذلك الحين، فهي وحدة واحدة. ومن الأمثلة يقود لمزيد من الدراسات أن ننظر في كيفية جافا <لأ href = "http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html" يختلط = "نوفولو noreferrer "> Iterator عادة ما يتم تنفيذها.

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

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

class Outer{

private int a;

class Inner{
private int b=0;
}

void outMethod(){
a = new Inner().b;
}
}

ولأن طريقة main() الخاص بك هو في الدرجة ABC، الذي <م> يمكن الوصول إلى الطبقة الداخلية الخاصة بها.

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