2010-01-09 6 views
5

में गैर-तत्काल कक्षा को विस्तारित करना मैंने यहोशू ब्लोच द्वारा "प्रभावी जावा" पढ़ा और हमारे आवेदन से 'कॉन्स्टेंट इंटरफेस एंटी-पैटर्न' को हटा दिया। चाल गैर-तत्काल उपयोग वर्ग का उपयोग करना है जिसका कन्स्ट्रक्टर निजी है, और सभी स्थिरांक को 'सार्वजनिक स्थिर अंतिम'जावा

मुझे इस निरंतर उपयोग वर्ग का विस्तार करना है। जब मैं संरक्षक को संरक्षित करने के लिए बदलता हूं तो मैं केवल यह कर सकता हूं।

क्या कोई बेहतर तरीका सुझा सकता है।

public class Constants { 
    private Constants() {} // Prevent instantiation 
    public static final String MyString = "MyString"; 
} 

public class MyConstants extends Constants { 
    private MyConstants() {} // Compiler error : Implicit super constructor Constants() is not visible. 
    public static final String MySecondString = "MySecondString"; 
} 
+3

आपको * कक्षा को विस्तारित करना क्यों है जो स्थिरांक रखता है? क्या आप वास्तव में उससे अधिक लाभ प्राप्त करते हैं (जैसा कि अलग-अलग वर्गों के विरोध में है जो एक दूसरे का विस्तार नहीं करते हैं)? – Jonik

+0

मैं सहमत हूं। धन्यवाद – Nayn

उत्तर

7

आपको आमतौर पर इन निरंतर कक्षाओं का विस्तार नहीं करना चाहिए। क्या आप हमें जो करने की कोशिश कर रहे हैं उसका एक और ठोस उदाहरण प्रदान कर सकते हैं?

आमतौर पर जब आप संबंधित होते हैं तो आप एक साथ स्थिरांक समूह बनाना चाहते हैं, उदाहरण के लिए, गणित स्थिरांक या किसी विशेष कार्यात्मक घटक के लिए कॉन्फ़िगरेशन पैरामीटर नाम।

यदि स्थिरांक वास्तव में संबंधित हैं, तो क्या आप उन्हें मूल कक्षा में जोड़ सकते हैं? वैकल्पिक रूप से, क्या कोई कारण है कि आप अपने स्थिरांक के लिए एक अलग वर्ग नहीं बना सकते हैं?

+1

बिल्कुल। यहां तक ​​कि मुझे लगता है कि हमें कॉन्स्टेंट कक्षाओं को बढ़ाने की जरूरत नहीं है। कोड विरासत है और मैं इसे ठीक कर दूंगा। बहुत बहुत धन्यवाद। – Nayn

2

मुझे संरक्षक को संरक्षित करने के साथ कुछ भी गलत नहीं दिख रहा है।

मुझे स्थिरांक रखने के लिए इंटरफेस का उपयोग करने में कुछ भी गलत नहीं दिख रहा है।

+4

"जब कोई वर्ग एक इंटरफेस लागू करता है, तो यह कक्षा के सार्वजनिक एपीआई का हिस्सा बन जाता है। कार्यान्वयन विवरण सार्वजनिक एपीआई में रिसाव नहीं होना चाहिए।" http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html। अधिक जानकारी के लिए प्रभावी जावा आइटम 17 देखें :) –

+1

मैं भावना को समझ सकता हूं, लेकिन मेरा मानना ​​है कि बहुत से लोग अपने आप को गठबंधन में डाल रहे हैं जो संभावित रूप से विरोधाभासी आवश्यकताओं के लिए सबसे अच्छा संभव समझौता खोजने की कोशिश कर रहे हैं, जबकि अन्य आगे बढ़ते हैं और चीजें करते हैं। जावा भाषा संस्कृति ने पैटर्न, सम्मेलनों और प्रतिबंधों के भ्रमित नेटवर्क में खुद को फेंकने में कामयाब रहा है, जो मुझे यकीन है कि अंत में अधिक उत्पादकता में योगदान नहीं है। लेकिन यह निश्चित रूप से मेरी व्यक्तिगत राय है। –

+4

मुझे लगता है कि कम विवादास्पद यह है कि * प्रभावी जावा * जैसे "नियम" एकल उपयोग, इन-हाउस परियोजनाओं की तुलना में सार्वजनिक उपयोग पुस्तकालयों और टूलकिट के लिए अधिक प्रासंगिक हैं। बार को उच्च रखने के लिए सूर्य, अपाचे और अन्य अत्यधिक दृश्य परियोजनाओं के लिए यह बहुत महत्वपूर्ण है। मेरी भावना यह है कि विभिन्न संदर्भ थोड़ा सा आसान साबित कर सकते हैं। –

1

क्या protected कीवर्ड का उपयोग करने में कोई समस्या है? यह मेरे लिए एक व्यावहारिक समाधान की तरह दिखता है।

मुझे कहना है (इसके अलावा) कि मुझे स्थिरांक रखने के लिए इंटरफ़ेस का उपयोग करने में कोई विशेष समस्या नहीं है। static import का उपयोग अपने क्लाइंट क्लास में उपलब्ध कराने के लिए करें। हालांकि, मैं इसे लागू करने का समर्थन नहीं करता।

+0

मुझे जरूरी नहीं है * इसे लागू करें, हालांकि ... –

+0

"इस के आसपास पाने के लिए, कभी-कभी लोग एक इंटरफ़ेस में स्थिर सदस्य और उस इंटरफ़ेस से प्राप्त होते हैं। यह एक बुरा विचार है। असल में, यह इतना बुरा विचार है कि इसके लिए एक नाम है: कॉन्स्टेंट इंटरफेस एंटीपाटन (प्रभावी जावा आइटम 17 देखें)। समस्या यह है कि एक वर्ग किसी अन्य वर्ग के स्थिर सदस्यों का उपयोग केवल एक कार्यान्वयन विस्तार है। जब एक वर्ग एक इंटरफ़ेस लागू करता है, तो यह कक्षा के सार्वजनिक एपीआई का हिस्सा बन जाता है। कार्यान्वयन विवरण सार्वजनिक एपीआई में रिसाव नहीं होना चाहिए। " http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html –

+0

@ ब्रायन आप इसे रोक नहीं सकते हैं, यही समस्या है। और आप किसी को अपने एपीआई का सही उपयोग नहीं करने के लिए दोष नहीं दे सकते (एपीआई दोषपूर्ण है, एपीआई का उपयोगकर्ता नहीं)। –

1

कक्षाएं एक ही पैकेज में रहे हैं और आप गैर पैकेज कक्षाओं के लिए विरासत न करे चाहते हैं, डिफ़ॉल्ट पहुँच का उपयोग करें:

public class Constants { 
    Constants() {} // Prevent instantiation 
    public static final String MyString = "MyString"; 
} 
3

मैं आमतौर पर निम्न करें:

public abstract class Constants { 
    // ...constants... 
    public Constants() { 
     throw new UnsupportedOperationException(); // prevent instantiation 
    } 
} 

यह जिस तरह से क्लास को व्युत्पन्न उपयोगिता वर्ग बनाने के लिए बढ़ाया जा सकता है, लेकिन किसी भी (गुमराह) प्रयास को तुरंत चालू करने का प्रयास विफल हो जाएगा। मैं java.util की इच्छा करता हूं। चयन इस तरह से परिभाषित किया गया था, इसलिए किसी को अतिरिक्त उपयोगिता विधियों के लिए संग्रह 2 (या समान) को परिभाषित करने की आवश्यकता नहीं होगी।

बीटीडब्ल्यू, एक अमूर्त वर्ग, "संरक्षित" और "सार्वजनिक" को प्रभावी ढंग से रचनाकारों के लिए समान है। वहाँ व्यावहारिक रूप से सिर्फ एक निर्माता संरक्षित करने में कोई लाभ नहीं किसी को अब भी आसानी से "सुरक्षा" के बावजूद वर्ग का एक उदाहरण बना सकते हैं के रूप में दिया गया है:

public class Base { 
    protected Base() { } 
} 

// Somewhere else: 
Base b = new Base() { }; // anonymous subclass 
0

मैं दृष्टिकोण यहोशू बलोच सिफारिश की गई है का उपयोग करें।

public class Constants { 

    private Constants() { 
     throw new AssertionError(); 
    } 

    public static class Math { 

     private Math() { 
      throw new AssertionError(); 
     } 

     public static final int COUNT = 12; 
    } 

    public static class Strings { 

     private Strings() { 
      throw new AssertionError(); 
     } 

     public static final String LOREM = "Lorem"; 
    } 

} 

Constants वर्ग और नेस्टेड कक्षाएं

  • नहीं बढ़ाई जा सकती

instantiated नहीं किया जा सकता है, तो मैं प्रकार के आधार पर समूह स्थिरांक की जरूरत, मैं करूंगा बस नेस्टेड कक्षाओं का उपयोग करें। याद रखें कि प्रत्येक नेस्टेड क्लास AssertionError फेंकना चाहिए।

+1

उस कोड के अधिकांश शोर को enums का उपयोग करके समाप्त किया जा सकता है। – Kevin