জাভা: এক ফাইলে একাধিক শ্রেণির ঘোষণা


238

জাভাতে, আপনি একক ফাইলে একাধিক শীর্ষ স্তরের শ্রেণি সংজ্ঞায়িত করতে পারেন, এটি সরবরাহ করে যে এর মধ্যে বেশিরভাগটি সর্বজনীন ( জেএলএস §§..6 দেখুন )। উদাহরণস্বরূপ নীচে দেখুন।

  1. এই কৌশল একটি পরিপাটি নাম (অনুরূপ inner, nested, anonymous)?

  2. JLS সিস্টেম বলেছেন হতে পারে সীমাবদ্ধতা যে এই মাধ্যমিক শ্রেণীর হতে পারে না জোরদার করা referred to by code in other compilation units of the package, যেমন, তারা প্যাকেজ-ব্যক্তিগত হিসাবে গণ্য করা যাবে না। এটি কি সত্যিই এমন কিছু যা জাভা বাস্তবায়নের মধ্যে পরিবর্তন হয়?

যেমন, পাবলিক ক্লাস.জভা:

package com.example.multiple;

public class PublicClass {
    PrivateImpl impl = new PrivateImpl();
}

class PrivateImpl {
    int implementationData;
}

11
+1 ভাল প্রশ্ন। আমি সত্যিই বিষয়টিটি খুব বেশি চিন্তা করি নি, যেহেতু এটি করার প্রয়োজন ছিল না।
মাইকেল ম্যাইইয়ার্স

12
নোট করুন যে এটি একটি অনুসন্ধানমূলক বৈশিষ্ট্য; জাভা প্রথম থেকেই ক্লাস করত যদি তা সম্ভব হত না।
কেভিন বোউরিলিয়ন

উত্তর:


120

এই কৌশলটির জন্য আমার প্রস্তাবিত নাম (একক উত্স ফাইলে একাধিক শীর্ষ-স্তরের শ্রেণি সহ) "গণ্ডগোল" হবে। গুরুতরভাবে, আমি এটি একটি ভাল ধারণা মনে করি না - আমি পরিবর্তে এই পরিস্থিতিতে নেস্টেড টাইপ ব্যবহার করব use তবে এটি কোন উত্স ফাইলটিতে রয়েছে তা অনুমান করা এখনও সহজ I আমি বিশ্বাস করি না যদিও এই পদ্ধতির জন্য কোনও সরকারী শব্দ নেই term

বাস্তবায়নের মধ্যে এটি আসলে পরিবর্তিত হয় কিনা - তা নিয়ে আমি অত্যন্ত সন্দেহ করি, তবে আপনি যদি এটি প্রথম দিকে করা থেকে বিরত থাকেন তবে আপনাকে কখনই যত্নের প্রয়োজন হবে না :)


71
আমি ডাউনভোটার নই, তবে সত্য এই উত্তরটি এমন একটি বিষয় যা "আদর্শিক" বলা যেতে পারে (যেমন। "আসলে" পরিবর্তে "আপনার উচিত" ... তবে ... ") এটির সর্বাধিক সম্ভাব্য কারণ আমি ভাবি একটি ডাউনोट পেতে। এটি আসলে কোনও প্রশ্নের উত্তর দেয় না। মতামতের পরিবর্তে প্রকৃত তথ্য সম্পর্কে তথ্য থাকা কোনও ব্যতিক্রম বাড়াতে / পরিবর্তে অপ্রাসঙ্গিক ব্যতিক্রম উত্থাপনের মতো।
n611x007

6
নেস্টেড টাইপ (যা আমি অন্যথায় একমত হতে চাই) ব্যবহার করার জন্য @ জোনস্কিটের পরামর্শের ক্ষেত্রে আমি যা মনে করি তা একটি সামান্য ব্যতিক্রম বলে মনে করেছি: যদি প্রধান শ্রেণিটি জেনেরিক হয় এবং টাইপ প্যারামিটারটি দ্বিতীয় শ্রেণি হয়, তবে দ্বিতীয় শ্রেণিটি পারে না নেস্টেড হতে। এবং যদি দুটি ক্লাসটি শক্তভাবে মিলিত হয় (যেমন প্রশ্নের মধ্যে পাবলিক ক্লাস এবং প্রাইভেটআইএমপিএল) তবে আমার মনে হয় প্রাইভেটআইপলকে একই ফাইলে শীর্ষ স্তরের শ্রেণি হিসাবে রাখা ভাল ধারণা।
jfritz42

6
@BoomerRogers: না, এই হ 'ল হয় না "কম্পোনেন্ট ভিত্তিক প্রোগ্রামিং কোর ভিত্তিতে"। আপনি যদি কোনও উপাদানটির বিরুদ্ধে প্রোগ্রামিং করছেন তবে উত্স কোডটি কীভাবে সংগঠিত হয়েছে তা আপনি কেন যত্ন করবেন? (ব্যক্তিগতভাবে আমি সার্ভিস লোকেটার প্যাটার্নের চেয়ে নির্ভরতা ইনজেকশনটিকেই পছন্দ করি তবে এটি আলাদা বিষয় API) আপনার মনে এপিআই এবং উত্স কোড সংগঠনটি আলাদা করুন - এগুলি খুব আলাদা জিনিস।
জন স্কিটি 22'14

1
@ জোনস্কিট আমাকে পুনরায় জবাব দিতে দিন: আপনার "উত্তর" একটি ব্যক্তিগত অপ্রাসঙ্গিক মতামত। (যেমন "জগাখিচুড়ি" এবং "আমি সন্দেহ করি" এর মতো উত্তরগুলির খুব কম মূল্য আছে)) সুতরাং, আপনার পোস্টটি 2 টি প্রশ্নের উত্থাপিত প্রশ্নের কোনও উত্তর দেয় না। পলিজেনুব্রিকেটেন্টগুলির উত্তরটি পরীক্ষা করে দেখুন এবং আপনি দেখতে পাবেন যে তিনি উভয়টিরই উত্তর পরিচালনা করেছেন।
বিভিডিবি

1
@ বিভিডিবি: (এবং এখানে প্রচুর জিনিস রয়েছে যা খারাপ অভ্যাস তবে অনুমানের দ্বারা অনুমোদিত I আমি লোকদেরকে অনুরোধ করব public int[] foo(int x)[] { return new int[5][5]; }যে এটি বৈধ হওয়া সত্ত্বেও সেগুলিও লেখেন না ))
জন স্কিটি

130

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

ধরুন আপনার কাছে দুটি ফাইল আছে, ফু.জাভা এবং বার.জাভা।

Foo.java এ রয়েছে:

  • পাবলিক ক্লাস ফু

বার.জাভাতে রয়েছে:

  • পাবলিক ক্লাস বার
  • ক্লাস বাজ

আসুন আমরা এটাও বলি যে ক্লাসের সমস্তগুলি একই প্যাকেজে (এবং ফাইলগুলি একই ডিরেক্টরিতে থাকে)।

Foo.java বাজকে বোঝায় তবে বার নয় এবং আমরা Foo.java সংকলনের চেষ্টা করলে কী হবে? সংকলনটি এই জাতীয় ত্রুটির সাথে ব্যর্থ হয়:

Foo.java:2: cannot find symbol
symbol  : class Baz
location: class Foo
  private Baz baz;
          ^
1 error

আপনি যদি এটি সম্পর্কে চিন্তা করেন তবে এটি অর্থবোধ করে। যদি ফু.জাভা বাজকে বোঝায় তবে বাজ.জাভা (বা বাজ.ক্লাস) নেই, জাভাক কীভাবে জানতে পারে কোন উত্স ফাইলটি সন্ধান করতে হবে?

আপনি যদি পরিবর্তে জাভাককে একই সাথে Foo.java এবং Bar.java সংকলন করতে বলেন, বা আপনি যদি আগে বার.জাভা সংকলন করেছিলেন (Baz.class ছেড়ে যেখানে জাভাক এটি সন্ধান করতে পারে) তবে এই ত্রুটিটি চলে যায়। তবে এটি আপনার বিল্ড প্রক্রিয়াটিকে খুব অবিশ্বাস্য এবং ঝাপটায় বোধ করে।

কারণ প্রকৃত সীমাবদ্ধতা, যা "অন্যরকম একটি ফাইল থেকে শীর্ষ স্তরের শ্রেণীর সাথে উল্লেখ করবেন না যদি না এটির যে ফাইলটি থাকে তেমন নাম না থাকে বা আপনি একই ক্লাসের সাথেও উল্লেখ করছেন যা একই ফাইলের নামকরণ করা হয় ফাইলটি যেমন "অনুসরণ করা একরকম কঠিন, লোকেরা সাধারণত প্রতিটি ফাইলে একটি শীর্ষ স্তরের শ্রেণি স্থাপনের অনেক বেশি সরল (যদিও কঠোর) কনভেনশন নিয়ে যান। ক্লাসটি সর্বজনীন হওয়া উচিত কিনা সে সম্পর্কে আপনি যদি নিজের মতামত পরিবর্তন করেন তবে এটি আরও ভাল।

কখনও কখনও সত্যিই প্রত্যেকে একটি নির্দিষ্ট উপায়ে কিছু করার উপযুক্ত কারণ রয়েছে।


সংকলনটিকে নির্ভরযোগ্য করে তোলার জন্য মাভেন কি কিছু করেন?
আলেকসান্দ্র ডাবিনস্কি

23

আমি বিশ্বাস করি আপনি কেবল PrivateImplএটি যা কল করেছেন : ক non-public top-level class। আপনি পাশাপাশি ঘোষণা করতে পারেন non-public top-level interfaces

উদাহরণস্বরূপ, এসও তে অন্য কোথাও: অ-পাবলিক শীর্ষ স্তরের শ্রেণি বনাম স্ট্যাটিক নেস্টেড ক্লাস

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


1
non-public top level classএটির সাথে আমার একমাত্র সমস্যাটি হ'ল আপনি কোনও ফাইলে একমাত্র শ্রেণি হতে পারেন , সুতরাং এটি বহুগুণকে সম্বোধন করে না।
মাইকেল ব্রুয়ার-ডেভিস

আমি উদ্বেগটি বুঝতে পারি, তবে আপনি দেখতে পাচ্ছেন এটি একটি পরিভাষা যা অন্যরা historতিহাসিকভাবে ব্যবহার করেছেন। যদি আমাকে নিজের শব্দটি তৈরি করতে হয় তবে আমি সম্ভবত এটি কল করব secondary top level types
বহুবিশ্লেষণকারী

7

আপনি যেমন চান তেমন ক্লাস করতে পারেন

public class Fun {
    Fun() {
        System.out.println("Fun constructor");
    }
    void fun() {
        System.out.println("Fun mathod");
    }
    public static void main(String[] args) {
        Fun fu = new Fun();
        fu.fun();
        Fen fe = new Fen();
        fe.fen();
        Fin fi = new Fin();
        fi.fin();
        Fon fo = new Fon();
        fo.fon();
        Fan fa = new Fan();
        fa.fan();
        fa.run();
    }
}

class Fen {
    Fen() {
        System.out.println("fen construuctor");

    }
    void fen() {
        System.out.println("Fen method");
    }
}

class Fin {
    void fin() {
        System.out.println("Fin method");
    }
}

class Fon {
    void fon() {
        System.out.println("Fon method");
    } 
}

class Fan {
    void fan() {
        System.out.println("Fan method");
    }
    public void run() {
        System.out.println("run");
    }
}

1
@ ননোতলেপ যখন আপনি "ফর্ম্যাটিংয়ের উন্নতি" করেন, তবে দয়া করে এটিও খেয়াল রাখবেন যে কোডটি নিজেই যেমন ব্যাকস্ল্যাশগুলি সরিয়ে ফেলছে তেমন কোনও গোলমাল না করে।
টম

3
যে প্রশ্নের উত্তর দেয় না।
01

4

1. এই কৌশলটির কোনও পরিপাটি নাম আছে (অভ্যন্তরের সাথে সাদৃশ্যযুক্ত, নীড়যুক্ত, বেনামে)?

বহু শ্রেণীর একক-ফাইল ডেমো।

২. জেএলএস বলছে যে সিস্টেমটি এই বিধিনিষেধ প্রয়োগ করতে পারে যে এই মাধ্যমিক শ্রেণিকে প্যাকেজের অন্যান্য সংকলন ইউনিটগুলিতে কোড দ্বারা উল্লেখ করা যায় না, উদাহরণস্বরূপ, তাদের প্যাকেজ-প্রাইভেট হিসাবে বিবেচনা করা যায় না। এটি কি সত্যিই এমন কিছু যা জাভা বাস্তবায়নের মধ্যে পরিবর্তন হয়?

আমার যে সীমাবদ্ধতা নেই সে সম্পর্কে আমি অবগত নই - সমস্ত ফাইল ভিত্তিক সংকলক আপনাকে শ্রেণীর নামের মতো নয় এমন ফাইলগুলিতে উত্স কোড শ্রেণি পড়তে অনুমতি দেবে না। (আপনি যদি একটি বহু-শ্রেণীর ফাইল সংকলন করেন এবং ক্লাসটিকে শ্রেণীর পথে রাখেন তবে যে কোনও সংকলক সেগুলি সন্ধান করতে পারে)


1

কার্যকর জাভা 2 য় সংস্করণ অনুসারে (আইটেম 13):

"যদি কোনও প্যাকেজ-বেসরকারী শীর্ষ-স্তরের শ্রেণি (বা ইন্টারফেস) কেবলমাত্র একটি শ্রেণীর দ্বারা ব্যবহৃত হয় তবে শীর্ষ স্তরের শ্রেণিকে এটি ব্যবহার করে এমন একমাত্র শ্রেণির ব্যক্তিগত নেস্টেড শ্রেণি হিসাবে বিবেচনা করুন (আইটেম 22) This এটি সকলের থেকে অ্যাক্সেসযোগ্যতা হ্রাস করে এটির প্যাকেজটিতে থাকা ক্লাসগুলি যে এক শ্রেণিতে এটি ব্যবহার করে a তবে এটি প্যাকেজ-বেসরকারী শীর্ষ স্তরের শ্রেণির চেয়ে কৃতজ্ঞভাবে পাবলিক ক্লাসের অ্যাক্সেসযোগ্যতা হ্রাস করা আরও গুরুত্বপূর্ণ: ... "

নেস্টেড বর্গটি স্থায়ী বা অ-স্থির হতে পারে তার ভিত্তিতে সদস্য শ্রেণীর সংলগ্ন দৃষ্টান্তটিতে অ্যাক্সেস প্রয়োজন (আইটেম 22)।


ওপি নেস্টেড ক্লাস সম্পর্কে জিজ্ঞাসা করছে না।
CharmoniumQ

0

হ্যাঁ আপনি যেমন বহিরাগত পাবলিক ক্লাসে পাবলিক স্ট্যাটিক সদস্যদের সাথে, এটি করতে পারেন:

public class Foo {

    public static class FooChild extends Z {
        String foo;
    }

    public static class ZeeChild extends Z {

    }

}

এবং অন্য একটি ফাইল যা উপরেরটি উল্লেখ করে:

public class Bar {

    public static void main(String[] args){

        Foo.FooChild f = new Foo.FooChild();
        System.out.println(f);

    }
}

তাদের একই ফোল্ডারে রাখুন। এর সাথে সংকলন:

javac folder/*.java

এবং সাথে চালান:

 java -cp folder Bar

সেই উদাহরণটি প্রশ্নের উত্তর দেয় না। আপনি নেস্টেড স্ট্যাটিক ক্লাসের একটি উদাহরণ দিচ্ছেন, যা একই ফাইলটিতে দুটি শীর্ষ স্তরের শ্রেণি নির্ধারণের মতো নয়।
পেড্রো গার্সিয়া মদিনা

0

শুধু এফওয়াইআই, আপনি যদি জাভা ১১+ ব্যবহার করেন তবে এই নিয়মের ব্যতিক্রম রয়েছে: আপনি যদি নিজের জাভা ফাইলটি সরাসরি চালান ( সংকলন ছাড়াই )। এই মোডে, ফাইলের জন্য একক পাবলিক ক্লাসে কোনও বিধিনিষেধ নেই। তবে, mainপদ্ধতিটি সহ ক্লাসটি অবশ্যই ফাইলের মধ্যে প্রথম হতে হবে।


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