2013-03-09 9 views
8

मेरे पास एक सारणी वर्ग है जो सार्वजनिक क्षेत्र को कार्यान्वित करना चाहिए, यह फ़ील्ड एक इंटरफेस या एक अन्य सार है।जावा अमूर्त वर्ग फ़ील्ड ओवरराइड

कुछ इस तरह:

public abstract class SpecialContainer extends GenericContainer { 
    public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE! 
} 

जावा मुझे इस संकलित करने के लिए अनुमति देते हैं, और मुझे लगता है कि क्षेत्र SpecialContainer में child स्वचालित रूप से अधिक भार है:

public abstract class GenericContainer { 
    public GenericChild child; 
} 

public abstract class GenericChild { 
    public int prop1=1; 
} 

public abstract class SpecialChild extend GenericChild { 
    public int prop1=2; 
} 

अब मैं एक और विशेष वर्ग कंटेनर है GenericContainer के क्षेत्र child ... प्रश्न हैं: क्या मैं इस पर सही हूं? बच्चे का स्वचालित 'ओवरलोडिंग' होगा?

और, अधिक महत्वपूर्ण सवाल है, अगर मैं इस तरह एक और वर्ग है:

public class ExternalClass { 
    public GenericContainer container=new SpecialContainer(); 
    public int test() { 
     return container.child.prop1 
    } 
} 

test() 1 या 2 वापस आ जाएगी? मेरा मतलब है GenericContainer कंटेनर फ़ील्ड क्या prop1 कॉल करेगा, जेनेरिक या विशेष? और क्या होगा यदि विशेष प्रो 1 को स्ट्रिंग के रूप में घोषित किया गया था (हाँ जावा मुझे इस मामले में भी संकलित करने की अनुमति देता है)?

धन्यवाद!

+4

सं क्षेत्रों अधिरोहित नहीं मिलता, केवल तरीकों से करते हैं। –

+0

तो यदि 'स्पेशल चाइल्ड' में मेरे पास एक तरीका है जो प्रो 1 का उपयोग करता है, तो उसे पहले कॉल पर क्या मिलेगा? 1 या 2? मैंने स्पेशल चाइल्ड से प्रोप 1 को आजमाया और निकालने के लिए मुझे स्पेशल चाइल्ड में एक विधि लिखने की अनुमति दी जो प्रोप 1 का उपयोग करता है अगर यह केवल जेनेरिक चाइल्ड में परिभाषित किया गया है ... तो मुझे लगता है कि एक प्रकार का अधिभार होता है ... – Alex

+4

आप हमेशा इसे _running कोशिश कर सकते हैं । –

उत्तर

8

यह कुछ भी नहीं है अधिभावी पर देखो, तुम सिर्फ वर्तमान वर्ग दायरे में मूल क्षेत्र छुपा रहे हैं। यदि आप उप प्रकार के साथ एक चर का उपयोग करते हैं तो भी आप मूल संपत्ति तक पहुंच पाएंगे। उदाहरण:

abstract class GenericContainer { 
    public GenericChild child;  
} 

abstract class GenericChild { 
    public int prop1=1 ; 
} 

class SpecialChild extends GenericChild { 
    public int prop1=2; 
} 

class SpecialContainer extends GenericContainer { 
    public SpecialChild child; 
} 

public class Main { 

    public static void main(String ... args) { 

     GenericContainer container = new SpecialContainer(); 
     container.child = new SpecialChild(); 

     System.out.println(container.child.prop1); 

     SpecialChild child = (SpecialChild) container.child;   
     System.out.println(child.prop1); 
    } 

} 

यह 1 प्रिंट और फिर 2.

SpecialChild से आप super का उपयोग कर एक स्तर ऊपर जाने के लिए सक्षम हो जाएगा:

class SpecialChild extends GenericChild { 
    public int prop1=2; 

    public int getOriginalProp1() { 
     return super.prop1; 
    } 

} 
+1

+1। –

2
के बारे में

.... और मुझे लगता है कि क्षेत्र "बच्चा" SpecialContainer में स्वचालित रूप से GenericContainer के क्षेत्र 'बच्चे' अधिक भार है ...

सं फील्ड्स डॉन ओवरराइड नहीं किया गया है, केवल तरीके ही करते हैं।

यह एक कारण है कि (ओवरड्रेबल) गेटटर और सेटटर विधियों का उपयोग फ़ील्ड तक पहुंच के लिए प्राथमिकता दी जाती है। आपके क्षेत्र लगभग सभी निजी होना चाहिए।

आपके डिज़ाइन के लिए, आपके स्पेशलकॉन्टेनर क्लास को स्पेशल चाइल्ड फ़ील्ड रखने की आवश्यकता नहीं है, लेकिन इसके बजाय स्पेशल चाइल्ड ऑब्जेक्ट जेनेरिक चाइल्ड फ़ील्ड में रखा जाना चाहिए।

1

जावा मुझे इस संकलित करने के लिए अनुमति देते हैं, और मुझे लगता है कि क्षेत्र "बच्चा" SpecialContainer में स्वचालित रूप से GenericContainer के क्षेत्र 'बच्चे' अधिक भार है ...

सबसे पहले, Inheritence चर पर लागू नहीं होता है। फ़ील्ड्स (इंटैटेंस चर) आपके उप-वर्ग में ओवरराइड नहीं हैं। वे केवल आपके उप-वर्ग में दिखाई दे रहे हैं यदि उन्हें public, protected or default के साथ चिह्नित किया गया है।

13

जावा में, डेटा सदस्य/विशेषताएं पॉलिमॉर्फिक नहीं हैं। ओवरलोडिंग का मतलब है कि उस क्षेत्र के आधार पर एक फ़ील्ड का अलग-अलग मूल्य होगा। उप-वर्ग में फ़ील्ड सुपर-क्लास में फ़ील्ड छिपाएगा, लेकिन दोनों मौजूद हैं। फ़ील्ड संदर्भ प्रकारों के आधार पर आविष्कार किए जाते हैं, जबकि वास्तविक वस्तु के तरीकों का उपयोग किया जाता है। आप इसे स्वयं आज़मा सकते हैं।

यह कहा जाता है, चर छुपा/छाया, अधिक जानकारी के लिए here

+2

धन्यवाद, यह वह जवाब है जो चीज़ों को स्पष्ट बनाता है! उदाहरण के लिए – Alex

1

आपके प्रश्न का उत्तर करने के लिए यह दोनों मामलों का कहना है । और इस पर निर्भर करता है कि आप कंटेनर को कैसे संदर्भित करते हैं (या तो सार या impl के माध्यम से) यह निर्धारित करता है कि आप किस चर का जिक्र कर रहे हैं।

public class Test { 

    public abstract class Container{ 
     public Generic gen = new Generic(); 
    } 

    public class ContainerImpl extends Container{ 
     public GenericImpl gen = new GenericImpl(); 
    } 

    public class Generic{ 
     public int prop = 0; 
    } 

    public class GenericImpl extends Generic{ 
     public int prop = 1; 
    } 

    public Test(){ 
     Container c = new ContainerImpl(); 
     System.out.println(c.gen.prop); // Outputs "0" 
     System.out.println(((ContainerImpl)c).gen.prop); // Output "1" 
    } 

    public static void main(String[] args) { 
     new Test(); 
    } 

} 

हाथ में बड़ा सवाल यह है कि आप ऐसा कुछ क्यों डिजाइन करेंगे? मुझे लगता है कि आप एक सैद्धांतिक परिप्रेक्ष्य से पूछ रहे हैं।

मेरा 2 सेंट, यह महान ओओ डिजाइन नहीं है। आप सार्वजनिक चर को निजी बनाने और कन्स्ट्रक्टर या प्रॉपर्टी सेटर के माध्यम से अपने मूल्यों को असाइन करने से बेहतर होंगे। जैसा कि, यह आपके कोड में अप्रत्याशित परिणाम का कारण बन जाएगा।

1

क्यों कोई भी नहीं है कि कार्यक्रम NullPointerException फेंक होगा अवलोकन कर रहा है।
उपclass के field उसी नाम के साथ सुपर क्लास field छुपाएगा। field के साथ overriding नहीं है। विधियों के साथ ओवरराइडिंग केवल संभव है। लेखक द्वारा

मूल कोड:

public abstract class GenericContainer { 
    public GenericChild child; 
} 

public abstract class GenericChild { 
    public int prop1=1; 
} 

public abstract class SpecialChild extend GenericChild { 
    public int prop1=2; 
} 

public abstract class SpecialContainer extends GenericContainer { 
    public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE! 
} 

public class ExternalClass { 
    public GenericContainer container=new SpecialContainer(); 
    public int test() { 
     return container.child.prop1 
    } 
} 
संबंधित मुद्दे