لماذا لا تستطيع إعلان فئة ثابتة في جافا؟

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

  •  01-10-2019
  •  | 
  •  

سؤال

لماذا لا تستطيع إعلان فئة ثابتة في جافا؟

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

المحلول

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

class OuterClass{
    public static class StaticNestedClass{
    }

    public class InnerClass{
    }

    public InnerClass getAnInnerClass(){
        return new InnerClass();
    }

    //This method doesn't work
    public static InnerClass getAnInnerClassStatically(){
        return new InnerClass();
    }
}

class OtherClass{
    //Use of a static nested class:
    private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();

    //Doesn't work
    private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();

    //Use of an inner class:
    private OuterClass outerclass= new OuterClass();
    private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
    private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}

مصادر :

حول نفس الموضوع:

نصائح أخرى

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

لذا ، أتأخر إلى الحفلة ، لكن هنا سنتان - أضيفوا فلسفيًا إلى إجابة كولن هيبرت.

على مستوى عال يتناول سؤالك الفرق بين الكائنات والأنواع. في حين أن هناك العديد من السيارات (الكائنات) ، لا يوجد سوى فئة سيارة واحدة (النوع). إن الإعلان عن شيء ثابت يعني أنك تعمل في مساحة "النوع". هناك واحد فقط. تحدد الكلمة الرئيسية للفئة العليا بالفعل نوعًا في مساحة "النوع". نتيجة "سيارة فئة ثابتة عامة" زائدة عن الحاجة.

فئة مع مُنشئ خاص ثابت.

أعلن صفك مثل هذا:

public class eOAuth {

    private eOAuth(){}

    public final static int    ECodeOauthInvalidGrant = 0x1;
    public final static int    ECodeOauthUnknown       = 0x10;
    public static GetSomeStuff(){}

}

ويمكنك استخدامها دون تهيئة:

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...

بالتأكيد يمكنهم ، ولكن فقط داخلي فصول متداخلة. هناك ، فهذا يعني أن مثيلات الفئة المتداخلة لا تتطلب مثيلًا مغلقًا للفئة الخارجية.

ولكن بالنسبة للفصول الدراسية العليا ، لم يتمكن مصممو اللغة من التفكير في أي شيء مفيد للتعرف على الكلمة الرئيسية ، لذلك لا يُسمح بذلك.

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

public enum MyUtilities {;
   public static void myMethod();
}
public class Outer {
   public static class Inner {}
}

... يمكن إعلانه ثابتًا - طالما أنه فئة عضو.

من JLS:

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

و هنا:

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

لن تكون الكلمة الرئيسية الثابتة لها أي معنى لفئة المستوى الأعلى ، لمجرد أن فئة المستوى الأعلى لا تحتوي على نوع مغلق.

كما هو موضح أعلاه ، لا يمكن أن يكون الفصل ثابتًا ما لم يكن عضوًا في فصل آخر.

إذا كنت تتطلع إلى تصميم فصل "لا يمكن أن يكون هناك حالات متعددة" ، فقد ترغب في النظر في نمط التصميم "Singleton".

معلومات المبتدئين هنا.

تنبيه قضائي:

إذا كنت تفكر في استخدام نمط Singleton ، قاوم مع كل قوتك. إنها واحدة من أسهل التصميمات التي لفهمها ، وربما الأكثر شعبية ، وبالتأكيد الأكثر إساءة معاملة. (المصدر: Javaranch كما هو الحال أعلاه)

بالإضافة إلى كيفية تعريف Java الفصول الداخلية الثابتة ، هناك تعريف آخر للفصول الساكنة وفقًا للعالم C# [1]. الطبقة الثابتة هي واحدة لها طرق ثابتة فقط (وظائف) ، ويهدف إلى دعم البرمجة الإجرائية. هذه الفئات ليست فئات حقًا حيث أن مستخدم الفصل مهتم فقط بوظائف المساعد وليس في إنشاء مثيلات من الفصل. بينما يتم دعم الفصول الساكنة في C#، لا يوجد مثل هذا الدعم المباشر في Java. ومع ذلك ، يمكنك استخدام التعدادات لتقليد الفئات الثابتة في Java حتى لا يتمكن المستخدم من إنشاء مثيلات من فئة معينة (حتى باستخدام الانعكاس) [2]:

public enum StaticClass2 {
    // Empty enum trick to avoid instance creation
    ; // this semi-colon is important

    public static boolean isEmpty(final String s) {
        return s == null || s.isEmpty();
    }
}

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

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

إذا كنت فقط تستبدل الكائن في كل مرة تقوم فيها بتشغيله ، فما هو الهدف من إنشائه؟

هذا هو السبب في تخلص جافا من الفئة الثابتة للفئة العليا.

قد يكون هناك المزيد من الأسباب الملموسة ، لكن هذا كان له معنى منطقي بالنسبة لي.

الفصول الوحيدة التي يمكن أن تكون ثابتة هي الفصول الداخلية. الرمز التالي يعمل بشكل جيد:

public class whatever {
    static class innerclass {
    }
}

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

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

public class StaticClass {

    static private int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

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

class StaticClass1 {

    public static int yum = 4;

    static void  printHowAreYou() {
        System.out.println("How are you?");
    }
}

public class StaticClass {

    static int me = 3; 
    public static void printHelloWorld() {
       System.out.println("Hello World");
       StaticClass1.printHowAreYou();
       System.out.println(StaticClass1.yum);
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

يمكن للمرء أن ينظر إلى PlatformUI في Eclipse لفصل مع أساليب ثابتة ومشارك خاص مع نفسه نهائي.

public final class <class name>
{
   //static constants
   //static memebers
}

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

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