2013-06-18 6 views
12

मान लीजिए मैं नीचे वर्ग है:जावा और विरासत में मिला स्थिर सदस्यों

class Parent 
{ 
    private int ID; 
    private static int curID = 0; 

    Parent() 
    { 
     ID = curID; 
     curID++; 
    } 
} 

और इन दो उपवर्गों:

class Sub1 extends Parent 
{ 
    //... 
} 

और

class Sub2 extends Parent 
{ 
    //... 
} 

मेरे समस्या यह है कि इन दो उपवर्गों हैं अलग-अलग होने के बजाय, अभिभावक वर्ग से समान स्थिर curid सदस्य साझा करना।

तो मैं यह नहीं करता है, तो:

{ 
    Sub1 r1 = new Sub1(), r2 = new Sub1(), r3 = new Sub1(); 
    Sub2 t1 = new Sub2(), t2 = new Sub2(), t3 = new Sub2(); 
} 

आईडी R1, R2 के, R3 0,1,2 और T1, T2 की, t3 3,4,5 हो जाएगा हो जाएगा। इनके बजाय मैं t1, t2, t3 मान 0,1,2 मानना ​​चाहता हूं, यानी curid स्थिर चर की एक और प्रति का उपयोग करें।

क्या यह संभव है? और कैसे?

+0

चर्चा में कुछ और विवरण: http://stackoverflow.com/questions/9898097/what-are-the-rules-dictating-the-inheritance-of -स्टैटिक-वेरिएबल्स-इन-जावा – sidshu

+0

कुछ और जानकारी http://stackoverflow.com/questions/9898097/what-are-the-rules-dictating-the-inheritance-of-static-variables-in-java – sidshu

उत्तर

9

जैसा कि अन्य पहले से ही लिखे गए हैं, स्थिर सदस्य वर्ग से बंधे हैं, इसलिए आपको कक्षा स्तर पर आईडी को ट्रैक करने की आवश्यकता है, उदाहरण के लिए इस तरह:

abstract class Parent { 
    private int ID; 

    Parent() { 
     ID = nextId(); 
    } 

    abstract protected int nextId(); 
} 

class Sub1 extends Parent { 
    private static int curID = 0; 

    protected int nextId() { 
     return curID++; 
    } 

    //... 
} 

class Sub2 extends Parent { 
    private static int curID = 0; 

    protected int nextId() { 
     return curID++; 
    } 

    //... 
} 

ध्यान दें कि यह दृष्टिकोण धागा सुरक्षित नहीं है - लेकिन सवाल में कोड भी नहीं था। आपको अलग-अलग धागे से समान उप वर्ग से नई वस्तुओं को नहीं बनाना चाहिए।

+2

यह ओपी की क्या ज़रूरत है, यह करने का यह एक अच्छा तरीका है, लेकिन मुझे लगता है कि यह उल्लेखनीय है कि इस तरह से स्थैतिक चर का उपयोग थ्रेड सुरक्षित नहीं है। इसके बजाय यहां सिंगलेट और फैक्ट्री विधियों का उपयोग करना एक अच्छा विचार हो सकता है। – RudolphEst

+0

@RudolphEst अच्छा बिंदु - अब समय से बाहर चल रहा है लेकिन यह मेरे उत्तर में जोड़ देगा –

1

स्टेटिक्स स्थिर हैं statics हैं। Curid, अवधि का केवल एक ही उदाहरण है। इसलिए यदि आप सब 1 और सब 2 के लिए अलग काउंटर चाहते हैं, तो आप उन वर्गों में से प्रत्येक में स्थैतिक घोषित करते हैं।

10

static फ़ील्ड/विधियां विरासत में नहीं मिली हैं। वे कक्षा के हैं, ऑब्जेक्ट संदर्भों के लिए नहीं।

+1

जेएलएस कुछ अलग कहता है: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4।8 एक कक्षा सी अपने प्रत्यक्ष सुपरक्लास से विरासत में प्राप्त होता है सुपरक्लास – MGorgon

+0

@ एमजीओआरओएन जेएलएस का सभी ठोस तरीकों एम (दोनों स्थिर और उदाहरण) का अर्थ है कि उप-वर्गों में यह विधि होगी लेकिन स्थिर होने के बाद ओवरराइड नहीं किया जा सकता है, जो व्यावहारिक रूप से वही है कि विधि विरासत में नहीं है, यह विधि लागू की तरह है। –

+1

मैं आपसे सहमत हूं, लेकिन औपचारिक रूप से जेएलएस सख्ती से निर्दिष्ट करता है कि स्थैतिक विधियां विरासत में हैं। यह कुछ उलझन में है, लेकिन ऑरैक प्रमाणीकरण में आपका जवाब गलत होगा। – MGorgon

0

विरासत स्थिर सदस्य का कोई मतलब नहीं है! स्टेटिक का अर्थ यह किसी दिए गए प्रकार के सभी उदाहरणों द्वारा साझा किया जाता है।

क्योंकि सब 1 और सब 2 दोनों प्रकार के माता-पिता हैं, समान स्थिर फ़ील्ड को साझा करते हैं।

मुझे लगता है कि यदि आपको लगता है तो आपको समस्याग्रस्त डिज़ाइन होने की संभावना है, आपको विरासत के साथ एक स्थिर क्षेत्र का उपयोग करने की आवश्यकता है।

कृपया वर्णन करें कि आप क्या करने की कोशिश कर रहे हैं इसके बारे में अधिक जानकारी दें।

0

स्थैतिक फ़ील्ड विरासत में नहीं मिलेगा। प्रत्येक उदाहरण एक ही क्षेत्र का उपयोग करेगा। जो कुछ आप चाहते हैं उसे पूरा करने के लिए मैं फ़ील्ड को एक इंस्टेंस फ़ील्ड में बदल दूंगा और या तो एक उदाहरण होगा जो आंतरिक रूप से इस क्षेत्र में वृद्धि करता है या यदि आपको तीन उदाहरण बनाने की आवश्यकता है तो आपके पास एक कन्स्ट्रक्टर हो सकता है जहां आप बढ़ी हुई मान को पास करते हैं।

1

स्टेटिक तत्वों को विरासत में नहीं मिला है।

वास्तव में Sub1.curID जैसी कोई चीज़ नहीं है - यह Persion.curID का संदर्भ देने का एक कानूनी (अभी तक भ्रमित) तरीका है।

दुर्भाग्य से स्थिर संदर्भों के साथ आप जो भी कर रहे हैं, उसके लिए कोई तरीका नहीं है। वे मूल रूप से अंतर्निहित के साथ काम नहीं करते हैं और काम नहीं कर सकते हैं - क्योंकि वे स्थिर रूप से हल किए गए हैं, वे गतिशील प्रेषण पर भरोसा नहीं कर सकते हैं और इसलिए रनटाइम बहुरूपता पर निर्भर नहीं हो सकते हैं। यह देखते हुए कि जेवीएम/कंपाइलर इस तरह स्थिर वैरिएबल का इलाज करता है, मुझे पूरा भरोसा है कि कोई कामकाज नहीं है जिसके साथ आप आ सकते हैं जो आपको वही करने देता है जो आप चाहते हैं।

यदि आईडी को वास्तव में स्थिर होने की आवश्यकता है, तो आपको प्रत्येक उप-वर्ग में अलग-अलग स्थैतिक चर परिभाषित करने की आवश्यकता होगी।

+0

जेएलएस कुछ अलग कहता है: http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8 एक कक्षा सी अपने प्रत्यक्ष सुपरक्लास से सभी ठोस तरीकों से प्राप्त होता है एम (सुपरक्लास – MGorgon

+0

@MGorgon दोनों स्थिर और उदाहरण) * वास्तव में * विधियों का वारिस नहीं करते हैं - आप उन्हें ओवरराइड नहीं कर सकते हैं, और चूंकि स्थिर संदर्भ संकलन समय पर हल किए जाते हैं, यह भी संभव नहीं होगा। यह सुपरक्लास 'विधि के लिए उपनाम की तरह है (मैं मानता हूं कि जेएलएस की भाषा भ्रामक है)। इसके अलावा, यहां मुद्दा विधियों के साथ नहीं बल्कि फ़ील्ड के साथ है - व्यवहार इस तथ्य के कारण है कि दोनों उपclasses एक ही 'curid' फ़ील्ड को संदर्भित करते हैं। –

0

static सदस्य Parent.class ऑब्जेक्ट का हिस्सा हैं जो PermGen जेवीएम के हिस्से में हैं। उस वर्ग के सभी उदाहरण समान स्थिर चर साझा करते हैं।

प्रत्येक उप-वर्ग का अपना static curID होना चाहिए।

+0

आह, ठीक है। एक जल्दबाजी के जवाब के लिए खेद है। – darijan

+0

मैंने डाउनवोट नहीं किया, लेकिन यह न केवल "कक्षा के उदाहरण" है जो समान स्थिर चर साझा करते हैं। यह बस इतना कोड है जो उस चर का उपयोग कर सकता है। – Ingo

0

आप उपयोग कर रहे हैं एक static चर

  • वहाँ अलग अलग वस्तुओं के लिए static चर का कोई प्रतियां, कर रहे हैं
  • वहाँ केवल static चर की प्रतिलिपि पर होगा और यह सभी उदाहरणों
  • के लिए साझा किया जाएगा
स्थिर चर विरासत के बारे में

, वे सब

पर inheritd नहीं कर रहे हैं

तुम कहते हो तो भले ही

r1.curID; 
t1.curID; 

यह एक ही बात, यानी मतलब होगा Parent.curID

आप वर्ग के उदाहरण से एक static चर बदल रहा है कर रहे हैं, और एक और उदाहरण है कि चर तक पहुँच रहा है, तो, यह बदले गए मूल्य को इसके साझा चर के रूप में प्राप्त करेगा

1

अन्य उत्तरों के विपरीत, आपकी समस्या का समाधान है, हालांकि इसमें "स्थिर विरासत" शामिल नहीं है। आपके पास प्रति-वर्ग आईडी जनरेटर होना चाहिए।

Java: Parent Methods accessing Subclasses' static variables?

2

यह संभव है, लेकिन एक भी काउंटर का उपयोग नहीं:

यहाँ एक अच्छा उदाहरण है। आपको एक उप-प्रकार प्रति काउंटर की आवश्यकता होगी। उदाहरण के लिए, निम्न की तरह कुछ:

private static Map<Class<?>, Integer> counters = new HashMap<>(); 

Parent() { 
    Integer curID = counters.get(this.getClass()); 
    if (curID == null) { 
     curID = 0; 
    } 
    ID = curID; 
    curID++; 
    counters.put(this.getClass(), curID); 
} 

सावधान रहें: उपरोक्त धागा-सुरक्षित नहीं है। लेकिन आपका प्रारंभिक कोड या तो नहीं है ...

संबंधित मुद्दे