2012-06-13 14 views
5

यह समस्या मुझे बगिंग चालू/बंद कर दी गई है और मैंने अब 4 रैपर लिखे हैं। मुझे यकीन है कि मैं इसे गलत कर रहा हूं और यह समझने की जरूरत है कि मेरी समझ कहां से बंद हो रही है।सी # आधार विरासत

मान लें कि मैं धातु के सलाखों का प्रतिनिधित्व करने के लिए आयताकार वर्ग का उपयोग कर रहा हूं। (यह जानवरों के बाद बेहतर काम करता है)

तो बेस क्लास को "बार" कहा जाता है।

private class Bar 
{ 
    internal Rectangle Area; 
} 

तो। अब हम एक आयत बनाते हैं, 300 इकाइयों को 10 इकाइयों द्वारा कहते हैं।

private Bar CreateBar() 
{ 
    Bar1 = new Bar1(); 
    Bar1.Area = new Rectangle(new Point(0,0), new Size(300,10)); 
    return Bar1; 
} 

शानदार, इसलिए हमारे पास बेस बार है।

अब मान लें कि हम इस बार को सामग्री बनाना चाहते हैं - स्टील कहें। इसलिए। । ।

private class SteelBar : Bar 
{ 
    string Material; 
} 

तो अगर मैंने ऐसा किया। । ।

private SteelBar CreateSteelBar() 
{ 
    SteelBar SteelB = new SteelB(); 
    Bar B = CreateBar(); 
    SteelB = B; 
    SteelB.Material = "Steel"; 
    return SteelB; 
} 

मैं क्या इस से मिलता है अगर मैं CreateSteelBar फोन से, यह एक steelbar कि CreateBar कॉल बनाता है। तो मैं 300 से 10 आयत के साथ एक स्टील बार के साथ समाप्त होता हूं, और सामग्री के लिए एक खाली या खाली स्ट्रिंग। फिर मैंने सामग्री को स्टील पर सेट किया।

जब मैं अपने कार्यक्रम में कुछ ऐसा करने की कोशिश करता हूं, तो यह कहता रहता है कि मैं निचले स्तर से उच्च श्रेणी के वर्ग को स्पष्ट रूप से नहीं बना सकता। मुझे लगता था कि यही कारण है कि विरासत उन जानवरों के उदाहरणों से प्राप्त सभी विरासतों पर विचार कर रही है, लेकिन मुझे उम्मीद है कि कोई मुझे साफ़ कर सकता है।

इसके अलावा, मुझे यकीन है कि मैं SteelBar = CreateBar(); पर कॉल कर सकता हूं लेकिन मैंने इसे लंबा सफर तय किया।

+3

यह मुझे स्पष्ट नहीं है कि आप रचनाकारों का उपयोग क्यों नहीं कर रहे हैं। इससे आपकी समस्या काफी सरल हो जाएगी। –

+0

आप 'CreateBar() ' –

+0

में मान वापस नहीं करते हैं यह इस मामले में होगा - मेरे सिस्टम में मैं उस चीज़ के लिए एक एक्सटेंशन बना रहा हूं जिसमें इसके अंदर 1 से 500 आइटम हैं। – Charles

उत्तर

16

बजाय एक विधि (CreateBar) होने के लिए, आप एक निर्माता का उपयोग करेंगे:

public SteelBar() 
{ 
    this.Material = "Steel"; 
} 

:

public Bar() 
{ 
    this.Area = new Rectangle(new Point(0,0), new Size(300,10)); 
} 

फिर, SteelBar में, आप आधार वर्ग निर्माता फोन करता हूँ बेस क्लास कन्स्ट्रक्टर पहले होगा, इसलिए आपका क्षेत्र पहले से ही सेटअप हो जाएगा। आप इस बारे में स्पष्ट किया जा सकता है, हालांकि, और अपने कोड में यह दिखाने:

public SteelBar() 
    : base() 
{ 
    this.Material = "Steel"; 
} 

बहरहाल, यह आमतौर पर केवल प्रयोग किया जाता है, तो आप एक विशिष्ट निर्माता है कि तर्क लेता करना चाहते हैं।

विवरण के लिए, सी # प्रोग्रामिंग मार्गदर्शिका में Constructors देखें।

Bar B = CreateBar(); 
SteelBar = B; 

यह वह जगह है सही नहीं है, क्योंकि एक ही नहीं हो सकता है, भले ही SteelBar चाहिए प्रकार Bar की हो (क्योंकि यह से विरासत में मिली):

+0

यह वास्तव में वांछित परिणाम प्राप्त करेगा, जैसा कि – Nevyn

+6

@KyleTrauberman में बताया गया है कि यह असत्य है - बेस क्लास कन्स्ट्रक्टर ** हमेशा ** को स्पष्ट रूप से बुलाया जाता है। यदि आप डिफॉल्ट, पैरामीटर रहित कन्स्ट्रक्टर के अलावा किसी कन्स्ट्रक्टर को कॉल करना चाहते हैं तो आपको केवल इसे निर्दिष्ट करने की आवश्यकता है। बेस क्लास कन्स्ट्रक्टर में से किसी एक को कॉल किए बिना सबक्लास बनाने का कोई तरीका नहीं है। –

+0

आप सही हैं। मैंने हमेशा इसे स्पष्ट रूप से बुलाया है। –

0

आप ऐसा नहीं कर सकते:

SteelBar = B; 

आप प्रकार बार की एक नई वस्तु बना लिया है और आप प्रकार SteelBar के संदर्भ निर्दिष्ट करने के लिए कोशिश कर रहे हैं।

0

मैं यकीन है कि आपकी समस्या आप Upcast की कोशिश कर रहे है कर रहा हूँ पीछे की ओर किया

विपरीत कानूनी होगा:

SteelBar B = CreateBar(); 
Bar = (Bar)B; 

काफी बस आप, Bar में SteelBar के संदर्भ स्टोर करने के लिए प्रयास कर रहे हैं, जबकि यह संभवतः इस तरह WoodenBar के रूप में एक और बार प्रकार हो सकता है।

Bar B = CreateBar(); 
SteelB = B; 

B किसी भी प्रकार की एक बार है:

3

यहाँ अपने समस्या है। आप इसे SteelBar पर असाइन करने का प्रयास कर रहे हैं। यह गलत है, यह किसी भी तरह का एक बार हो सकता है (तांबे, लकड़ी, Tiki, ...)। आप ऐसा कर सकते हैं:

SteelBar sb = new SteelBar(); 
Bar b = sb; 

क्योंकि एक SteelBar किसी तरह का एक बार भी है, लेकिन रिवर्स सच नहीं है ..

इसके अलावा, मैं कुछ मैं कह सकते हैं SteelBar = CreateBar()
हूँ

आप कुछ ऐसा है जो झूठा है। कोशिश करो; CreateBar किसी भी प्रकार की बार का एक उदाहरण देता है, SteelBar नहीं।

1

pycruft उल्लेख किया है आप एक उप-प्रकार-चर करने के लिए एक basetype की एक वस्तु नहीं सौंप सकते। मुझे समझ में नहीं आता कि आप SteelBar क्यों जोड़ते हैं, क्योंकि आपके पास Material संपत्ति भी है। यह मेरे लिए अनावश्यक लग रहा है।

प्राप्त करने के लिए आपको बस इतना करना कोशिश कर रहे हैं क्या, आप एक नया कारखाना विधि है कि शुरू से ही एक SteelBar बनाता है बनाने के लिए किया है। यह इसे किसी भी तरह Bar के रूप में वापस कर सकता है। यह Factory Pattern का कार्यान्वयन होगा।

हालांकि, आप जो हासिल करने की कोशिश कर रहे हैं उसके बारे में कुछ और जानकारी मदद कर सकते हैं।

0

निश्चित रूप से इस तरह के इंटरफेस ... जैसे के रूप में कपोल-कल्पना के साथ प्राप्त करने के लिए आसान होगा अप्राप्य और भौतिक और आधार वर्ग नहीं ...

मैं केवल उन्हें प्रदर्शित करने के लिए जीयूआई प्रतिनिधित्व में बेस क्लास का उपयोग करता हूं और मैं बेस क्लास को आवश्यक इंटरफेस को लागू करने के लिए मजबूर करता हूं।

तुम भी वैकल्पिक रूप से कर सकता है एक DisplayObject जो सील और एक IMeasurable या IPhysical लेता है ...

1

का उपयोग यह मैं परोक्ष एक नीचे निम्न वर्ग से एक उच्च ऊपर वर्ग नहीं बना सकते कह रहता है

इस के लिए सबसे अच्छा उदाहरण मैं उपयोग करता हूं Fruit और apple है। विरासत एक "एक-एक" संबंध है।एक apple है-एक Fruit लेकिन एक Fruit एक apple के रूप में यह हो सकता है एक orange, banana ...

अपने उदाहरण पर वापस, एक SteelBar एक Bar है नहीं है, लेकिन एक Bar एक SteelBar यह कर सकते हैं के रूप में नहीं है एक WoodenBar हो सकता है और है कि यही कारण है कि आप इस उदाहरण पर विचार बच्चे वर्ग

0

को सुपर वर्ग कास्ट नहीं कर सकते हैं:

public class Super { 
} 

public class Sub : Super { 
} 

यदि आप ऑब्जेक्ट सुपर बनाते हैं तो आप इसे सब के रूप में असाइन नहीं कर सकते क्योंकि यह "सब" नहीं है। ओओ प्रोग्रामिंग आपको कम व्युत्पन्न कक्षाओं के संदर्भ में वस्तुओं से निपटने की अनुमति देती है लेकिन यह सरल तथ्य अभी भी बनी हुई है:

आपने सुपर सुपर सब बनाया है।

एक सुपर से उप बनाने का एकमात्र तरीका एक नया उप और संपत्ति मूल्यों की प्रतिलिपि बनाना होगा। ऑटोमैपर जैसे टूल को जल्दी से ऐसा करने के लिए अच्छा काम करता है अन्यथा आप सांसारिक भंगुर कोड की रेखाओं के समूह के साथ समाप्त हो जाएंगे।

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