বাইরের জাভা ক্লাসগুলি কেন অভ্যন্তরীণ শ্রেণীর ব্যক্তিগত সদস্যদের অ্যাক্সেস করতে পারে?


177

আমি পর্যবেক্ষণ করেছি যে বহিরাগত ক্লাসগুলি অভ্যন্তরীণ ক্লাসগুলির প্রাইভেট ইনস্ট্যান্স ভেরিয়েবলগুলি অ্যাক্সেস করতে পারে। এটা কিভাবে সম্ভব? এখানে একই নমুনা কোড প্রদর্শন করছে:

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??
    }
}

কেন এই আচরণ অনুমোদিত?


আমি মন্তব্যটি না পাওয়া পর্যন্ত এই প্রশ্নটি আমাকে বেশ কিছুক্ষণ বিভ্রান্ত করেছে ... যা আমার মেশিনে xx.x অ্যাক্সেস করতে পারছি না তা ব্যাখ্যা করে ...
ওয়াং শেং

4
মন্তব্যগুলি আমাকে বিভ্রান্ত করেছে, আমি উপরের কোডটি জাভা 8 তে চালাই, এটি সংকলন এবং চালায় does xx.x অ্যাক্সেস করা যায়।
লিওন

হরিশ, আপনি কি দয়া করে গৃহীত উত্তরটি অ-গ্রহণ করতে পারেন (যা আপনি জিজ্ঞাসা করা প্রশ্নের উত্তর দেয় না) এবং পরিবর্তে নীচে মার্টিন অ্যান্ডারসনের উত্তরটি মেনে নিতে পারেন, যা এটির পুরোপুরি উত্তর দেয়?
অস্থায়ী_ ব্যবহারকারী_নাম

FWIW এই বাক্যবিন্যাসটি একেবারে ভয়াবহ:new ABC().new XYZ()
জোশ এম।

উত্তর:


79

অভ্যন্তরীণ শ্রেণীটি এমন কিছু কার্যকারিতা পরিষ্কারভাবে পৃথক করার একটি উপায় যা আসল বাহ্যিক শ্রেণীর অন্তর্গত। যখন আপনার 2 টি প্রয়োজনীয়তা রয়েছে তখন সেগুলি ব্যবহার করার উদ্দেশ্যে তৈরি হয়:

  1. আপনার বাইরের শ্রেণিতে কার্যকারিতার কিছু অংশ যদি এটি পৃথক শ্রেণিতে প্রয়োগ করা হয় তবে সর্বাধিক স্পষ্ট হবে।
  2. যদিও এটি একটি পৃথক শ্রেণিতে রয়েছে, বহিরাগত শ্রেণি যেভাবে কাজ করে তার সাথে কার্যকারিতা খুব ঘনিষ্ঠভাবে আবদ্ধ।

এই প্রয়োজনীয়তাগুলি দেওয়া, অভ্যন্তরীণ ক্লাসগুলির তাদের বাইরের শ্রেণিতে সম্পূর্ণ অ্যাক্সেস রয়েছে। যেহেতু তারা মূলত বহিরাগত শ্রেণীর সদস্য, তাই এটি বোঝা যায় যে তারা ব্যক্তিগত এবং বহিরাগত শ্রেণির বৈশিষ্ট্যগুলিতে অ্যাক্সেস পেয়েছে।


217
এই উত্তরটি ব্যাখ্যা করে যে কেন নেস্টেড ক্লাসগুলি তাদের বাইরের শ্রেণির ব্যক্তিগত সদস্যদের অ্যাক্সেস করে। তবে প্রশ্ন হল কেন বাইরের শ্রেণিতে নেস্টেড ক্লাসগুলির ব্যক্তিগত সদস্যদের অ্যাক্সেস রয়েছে?
অ্যান্ড্রু

13
এই প্রয়োজনীয়তাগুলি প্রদানের জন্য কেবল "এবং তদ্বিপরীত" যুক্ত করুন , অভ্যন্তরীণ ক্লাসগুলির তাদের বাইরের শ্রেণিতে সম্পূর্ণ অ্যাক্সেস রয়েছে এবং এখন এটি প্রশ্নের উত্তর দেয়।
অ্যানথ্রোপোমো

13
এটি এই সমস্যার সঠিক উত্তর নয়, এখানে এটি করেছেন: stackoverflow.com/questions/19747812/…
কলিন সু

4
@ অ্যানথ্রোপোমো: না, তা হয় না। উভয় প্রয়োজনীয়তা বাইরের শ্রেণীর অভ্যন্তরীণ শ্রেণীর ব্যক্তিগত সদস্যদের কোনও অ্যাক্সেস না করে একেবারে সম্ভাব্য।
অথবা ম্যাপার

একটি বিশেষ উদাহরণ যেখানে এটি বিশেষভাবে কার্যকর তা হ'ল বিল্ডার প্যাটার্ন, স্ট্যাকওভারফ্লো . com / a / 1953567 / 1262000 । অভিভাবক শ্রেণীর জন্য কেবল এমন একজন নির্মাতা প্রয়োজন যা একজন নির্মাতা নেয় এবং এর সমস্ত সদস্যের ভেরিয়েবল অ্যাক্সেস করে। অন্যথায় আপনার সমস্ত ব্যক্তিগত সদস্যের ভেরিয়েবলগুলি সহ প্যারেন্ট ক্লাসে একটি প্রাইভেট কনস্ট্রাক্টর থাকা দরকার।
vikky.rk

62

আপনি যদি নিজের অভ্যন্তর শ্রেণীর ব্যক্তিগত সদস্যদের আড়াল করতে চান, আপনি জনসাধারণের সাথে একটি ইন্টারফেস সংজ্ঞায়িত করতে পারেন এবং একটি বেনামি অভ্যন্তরীণ শ্রেণি তৈরি করতে পারেন যা এই ইন্টারফেসটি প্রয়োগ করে। নমুনা উদাহরণ:

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
    }
}

এটি কোডের একটি উজ্জ্বল স্নিপেট। ঠিক যেটা আমার দরকার ছিল. ধন্যবাদ!
কেভিনার্পে

দয়া করে কোড সরবরাহ করুন যা চালাতে সক্ষম হতে পারে। আরও কী কারণে ব্যক্তিগত ভেরিয়েবল অ্যাক্সেসের অনুমতি দেওয়া যায়নি তার কারণ দয়া করে।
অ্যান্ড্রয়েড

7
তবে তারপরে ... অভ্যন্তর শ্রেণি বেনামে। আপনি সেই অভ্যন্তর শ্রেণির বেশ কয়েকটি দৃষ্টান্ত তৈরি করতে পারবেন না, বা কোনও পরিবর্তনশীল ঘোষণা ইত্যাদির জন্য inner অভ্যন্তরীণ বর্গটি ব্যবহার করতে পারবেন না
অথবা ম্যাপার

@ ওআর ম্যাপার এজন্য xএখানে সর্বজনীন হলেও , এটির মতো অনুমোদিত নয় mMember.x
ম্যাক

53

অভ্যন্তরীণ বর্গটি (অ্যাক্সেস নিয়ন্ত্রণের উদ্দেশ্যে) ধারণকারী শ্রেণীর অংশ হিসাবে বিবেচিত হয়। এর অর্থ সমস্ত বেসরকারীদের সম্পূর্ণ অ্যাক্সেস।

এটি প্রয়োগ করার পদ্ধতিটি সিন্থেটিক প্যাকেজ-সুরক্ষিত পদ্ধতিগুলি ব্যবহার করে: অভ্যন্তরীণ শ্রেণি একই প্যাকেজের (এবিসি $ এক্সওয়াইজেড) পৃথক শ্রেণিতে সংকলিত হবে। জেভিএম সরাসরি এই স্তরটিকে বিচ্ছিন্নভাবে সমর্থন করে না, যাতে বাইটকোড-স্তরে এবিসি-এক্সওয়াইজেডের প্যাকেজ-সুরক্ষিত পদ্ধতি রয়েছে যা বহিরাগত শ্রেণি ব্যক্তিগত পদ্ধতি / ক্ষেত্রগুলিতে যেতে ব্যবহার করে।


17

এর অনুরূপ অন্য প্রশ্নের উপর একটি সঠিক উত্তর উপস্থিত হচ্ছে: নীড়যুক্ত শ্রেণীর ব্যক্তিগত সদস্য কেন ঘেরের ক্লাসের পদ্ধতিগুলি দ্বারা অ্যাক্সেস করা যায়?

এটি বলেছে যে জেএলএসে ব্যক্তিগত স্কোপিংয়ের একটি সংজ্ঞা রয়েছে - অ্যাক্সেসিবিলিটি নির্ধারণ :

অন্যথায়, যদি সদস্য বা কনস্ট্রাক্টরকে ব্যক্তিগত হিসাবে ঘোষণা করা হয়, তবে কেবলমাত্র শীর্ষ স্তরের শ্রেণীর (§§..6) সদস্য বা কনস্ট্রাক্টরের ঘোষণাকে ঘিরে যদি এটি ঘটে তখনই অ্যাক্সেসের অনুমতি দেওয়া হয়।


আমি মনে করি এই স্নিপেটটি আমার প্রশ্নের সুন্দর উত্তর দিতে পারে।
শেন

5

অভ্যন্তরীণ ক্লাসগুলির জন্য একটি আইএমএইচও গুরুত্বপূর্ণ ব্যবহারের ক্ষেত্রটি হ'ল কারখানার ধরণ। সংযুক্তকারী শ্রেণি অভ্যন্তরীণ শ্রেণীর ডাব্লু / ও অ্যাক্সেস সীমাবদ্ধতার একটি উদাহরণ প্রস্তুত করতে পারে এবং উদাহরণটি বাইরের বিশ্বে পাস করতে পারে, যেখানে ব্যক্তিগত প্রবেশাধিকার সম্মানিত হবে।

অ্যাটাকের বিপরীতে শ্রেণি স্থির ঘোষণার দ্বারা নীচে দেখানো মত, বদ্ধ শ্রেণিতে অ্যাক্সেস বিধিনিষেধ পরিবর্তন হয় না। একই বদ্ধ শ্রেণিতে স্থির শ্রেণীর মধ্যে অ্যাক্সেস বিধিনিষেধ কাজ করছে। আমি অবাক হই ...

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);
    }
}

1
ভাল মন্তব্য কিন্তু কোন উত্তর।
সিলিং

@ নির্ধারণ এটি আসলে একমাত্র উত্তর যা আমাকে অন্যথায় উদ্ভট ডিজাইনের সিদ্ধান্তের ব্যবহারিক বাস্তব ব্যবহার দেখতে দেয়। এই প্রশ্নটি কেন এইভাবে সিদ্ধান্ত নেওয়া হয়েছিল, এবং এটি একটি দুর্দান্ত যুক্তি - আপনি বাইরের শ্রেণীর অভ্যন্তরীণ শ্রেণিতে কী কী অ্যাক্সেস পেতে চান এবং অন্যান্য অপ্রাসঙ্গিক শ্রেণীর অ্যাক্সেসের জন্য কী চান তার মধ্যে পার্থক্যের একটি প্রদর্শন।
এট_ল

3

অ্যাক্সেস বিধিনিষেধ প্রতি ক্লাস ভিত্তিতে করা হয়। কোনও ক্লাসে ঘোষিত কোনও পদ্ধতির পক্ষে দৃষ্টান্তের সমস্ত শ্রেণি / সদস্যদের অ্যাক্সেস না করার পক্ষে উপায় নেই। এটি এই কারণেই দাঁড়ায় যে অভ্যন্তরীণ শ্রেণিতেও বহিরাগত শ্রেণীর সদস্যদের অবিচ্ছিন্ন প্রবেশাধিকার রয়েছে এবং বাইরের শ্রেণীর অভ্যন্তরীণ শ্রেণীর সদস্যদের নিরক্ষিত প্রবেশাধিকার রয়েছে।

অন্য শ্রেণীর ভিতরে একটি শ্রেণি স্থাপন করে আপনি এটি প্রয়োগের সাথে দৃ tight়ভাবে আবদ্ধ করছেন এবং বাস্তবায়নের অংশ এমন যে কোনও কিছুতে অন্যান্য অংশে অ্যাক্সেস থাকা উচিত।


3

অভ্যন্তরীণ ক্লাসগুলির পিছনে যুক্তিটি হ'ল যদি আপনি কোনও বাহ্যিক শ্রেণিতে একটি অভ্যন্তরীণ শ্রেণি তৈরি করেন, কারণ তাদের কয়েকটি জিনিস ভাগ করে নেওয়া দরকার এবং এইভাবে তাদের "নিয়মিত" শ্রেণীর চেয়ে আরও নমনীয়তা অর্জন করতে সক্ষম হওয়া বোধগম্য।

যদি, আপনার ক্ষেত্রে, ক্লাসগুলি একে অপরের অভ্যন্তরীণ কাজগুলি দেখতে সক্ষম হওয়ার কোনও অর্থ দেয় না - যার মূলত অর্থ এই যে অভ্যন্তরীণ শ্রেণিটি কেবল একটি নিয়মিত শ্রেণি হিসাবে তৈরি করা যেতে পারে তবে আপনি অভ্যন্তরীণ শ্রেণিকে যেমন ঘোষণা করতে পারেন static class XYZ। ব্যবহার staticতারা করবে না ভাগ রাষ্ট্র মানে হবে (এবং, উদাহরণস্বরূপ new ABC().new XYZ()না কর্ম, আর তোমাদের ব্যবহার করতে হবে new ABC.XYZ()
, কিন্তু সেই বিষয়টিই কিনা তা, আপনি কিনা চিন্তা করা উচিত XYZসত্যিই একটি ভেতরের বর্গ হওয়া উচিত এবং হয়তো এটা তার নিজস্ব দাবী ফাইল। কখনও কখনও স্থির অভ্যন্তর শ্রেণি তৈরি করা বোধগম্য হয় (উদাহরণস্বরূপ, আপনার যদি একটি ছোট শ্রেণীর প্রয়োজন হয় যা আপনার বাইরের শ্রেণিটি ব্যবহার করছে এমন ইন্টারফেস প্রয়োগ করে এবং এটি অন্য কোথাও সহায়ক হবে না) তবে প্রায় অর্ধেক সময় এটি একটি বাইরের শ্রেণি করা উচিত ছিল।


2
বহিরাগত শ্রেণি স্ট্যাটিকের ব্যক্তিগত সদস্যদের অ্যাক্সেস করতে পারে যেমন অভ্যন্তর শ্রেণীর পারে, তাই এটি স্ট্যাটিকের সাথে কোনও সম্পর্ক রাখে না । আপনি বলছেন "ক্লাসগুলি একে অপরের অভ্যন্তরীণ কাজগুলি দেখতে সক্ষম হওয়ার কোনও মানে রাখে না", তবে এটি অবশ্যই প্রয়োজন নয় - যদি কেবল অভ্যন্তরীণ শ্রেণীর বাইরের শ্রেণীর অভ্যন্তরীণ কাজগুলি দেখার জন্য তা বোধ হয় তবে ভাইস-না বিপরীতভাবে?
অথবা ম্যাপার

3

থিলো আপনার প্রথম প্রশ্নের "এটি কীভাবে সম্ভব?" এর জন্য একটি ভাল উত্তর যুক্ত করেছে। দ্বিতীয় জিজ্ঞাসিত প্রশ্নটির বিষয়ে আমি কিছুটা বিশদভাবে জানাতে চাই: কেন এই আচরণের অনুমতি দেওয়া হচ্ছে?

প্রারম্ভিকদের জন্য, আসুন পুরোপুরি স্পষ্ট হওয়া উচিত যে এই আচরণটি কেবল অভ্যন্তর শ্রেণীর মধ্যেই সীমাবদ্ধ নয়, যা সংজ্ঞা অনুসারে অ-স্থিত নেস্টেড প্রকারের। এই আচরণটি নেস্টেড এনামস এবং ইন্টারফেসগুলি সহ সমস্ত নেস্টেড ধরণের জন্য অনুমোদিত যা অবশ্যই স্থির থাকতে হবে এবং এতে কোনও ঘেরের উদাহরণ থাকতে পারে না। মূলত, মডেলটি নিম্নলিখিত বিবৃতিটির সরলকরণ: নেস্টেড কোডের এনকোলেসিং কোডে সম্পূর্ণ অ্যাক্সেস রয়েছে - এবং তদ্বিপরীত।

তো, তাহলে কেন? আমি মনে করি একটি উদাহরণ পয়েন্টটি আরও ভালভাবে বর্ণনা করে।

আপনার শরীর এবং আপনার মস্তিষ্কের কথা চিন্তা করুন। আপনি যদি আপনার বাহুতে হেরোইন ইনজেকশন করেন তবে আপনার মস্তিষ্ক উচ্চ হয়ে যায়। যদি আপনার মস্তিষ্কের অ্যামিগডালা অঞ্চলটি দেখতে পান যে তিনি কী বিশ্বাস করেন যা আপনার ব্যক্তিগত সুরক্ষার জন্য হুমকি, উদাহরণস্বরূপ একটি বর্জ্য বলুন, তিনি আপনার দেহটিকে অন্যদিকে ঘুরিয়ে দেবেন এবং এটি সম্পর্কে আপনি "চিন্তা" না করে দু'বার পাহাড়ের দিকে ছুটে যাবেন।

সুতরাং, মস্তিষ্ক শরীরের একটি অন্তর্নিহিত অঙ্গ - এবং আশ্চর্যজনকভাবে যথেষ্ট, অন্যদিকেও। ঘনিষ্ঠভাবে সম্পর্কিত সংস্থাগুলির মধ্যে অ্যাক্সেস নিয়ন্ত্রণ ব্যবহার করে তাদের সম্পর্কের দাবিটি হারাতে হবে। আপনার যদি অ্যাক্সেস নিয়ন্ত্রণের প্রয়োজন হয় তবে আপনার ক্লাসগুলি আরও সত্যিকারের স্বতন্ত্র ইউনিটে আলাদা করতে হবে। ততক্ষণে তারা একই ইউনিট। আরও অধ্যয়নের জন্য একটি ড্রাইভিং উদাহরণ Iteratorহ'ল জাভা সাধারণত কীভাবে প্রয়োগ করা হয় তা দেখা।

নেস্টেড কোডে এনকোলেজিং কোড থেকে সীমাহীন অ্যাক্সেস এটিকে বেশিরভাগ অংশে, ক্ষেত্র এবং নেস্টেড ধরণের পদ্ধতির পদ্ধতিতে অ্যাক্সেস মডিফায়ার যুক্ত করার পরিবর্তে অকেজো। এটি করা বিশৃঙ্খলা যুক্ত করছে এবং জাভা প্রোগ্রামিং ভাষার নতুন আগতদের জন্য একটি মিথ্যা সুরক্ষার ধারণা প্রদান করবে।


1
এটি সত্যই গ্রহণযোগ্য উত্তর হওয়া উচিত। তাই পরিষ্কার এবং পুঙ্খানুপুঙ্খ। পরিবর্তে গৃহীত উত্তর এমনকি প্রশ্নের সমাধান করে না।
অস্থায়ী_ ব্যবহারকারী_নাম

আইএমও এটি এখনও কেন কোনও অভ্যন্তরীণ শ্রেণিতে ব্যক্তিগত ক্ষেত্রগুলি সহজেই যুক্ত করতে পারি না, যা বহিরাগত শ্রেণি সরাসরি অ্যাক্সেস করতে পারে না সে প্রশ্নের প্রশ্নের উত্তর দেয় না। আমি ভুল না হলে এটি অভ্যন্তরীণ শ্রেণীর জন্য প্রাথমিক কেসগুলির একটি ধ্বংস করে দেয় - স্বল্পকালীন "কাঠামোর মতো" তৈরি করে, অপরিবর্তনীয় প্রকারের। এফডব্লিউআইডাব্লু সি # আনন্দের সাথে এটি সমর্থন করে: repl.it/repls/VengefulCheeryInverse
জোশ এম

-1

ইনার ক্লাসটি আউটার ক্লাসের একটি অ্যাট্রিবিউট হিসাবে বিবেচিত হয়। অতএব, অভ্যন্তরীণ শ্রেণীর উদাহরণ পরিবর্তনশীলটি ব্যক্তিগত বা না তা কোনও ব্যাপার নয়, আউটার শ্রেণি যেমন তার অন্যান্য ব্যক্তিগত বৈশিষ্ট্য (ভেরিয়েবল) অ্যাক্সেস করার মতো কোনও সমস্যা ছাড়াই অ্যাক্সেস করতে পারে।

class Outer{

private int a;

class Inner{
private int b=0;
}

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

-2

কারণ আপনার main()পদ্ধতিটি ABCক্লাসে রয়েছে, যা নিজের অভ্যন্তর শ্রেণিতে অ্যাক্সেস করতে পারে


2
ABCক্লাসের সদস্যরা ক্লাসে বাসা বেধে থাকা ক্লাসগুলি অ্যাক্সেস করতে পারে কিনা তা নয় ABC, তবে কেন তারা জাভাতে ক্লাসে বাসা বেঁধে থাকা শ্রেণীর ব্যক্তিগত সদস্যদের অ্যাক্সেস করতে পারেন ABC
অথবা ম্যাপার

আমি যেদিন জিজ্ঞাসা করা হয়েছিল সেদিনই আমি উত্তরটি দিয়েছি। কেউ প্রশ্নটি 2 বছর পরে সম্পাদনা করেছে, এবং ডাউনওয়েটটি 3 বছর পরে এসেছিল। আমি নিশ্চিত যে প্রশ্নটি সম্পাদনা করেছেন তিনি প্রশ্নের শব্দকে পুরোপুরি পরিবর্তন করেছেন।
aberrant80
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.