2012-09-03 4 views
29

मुझे वास्तव में यकीन नहीं है कि मैं वास्तव में क्या दिखता हूं या वास्तव में सार वर्गों और गुणों में कब उपयोग करता हूं, या गैर अमूर्त गुणों का उपयोग कब करता हूं। मैं एक साधारण उदाहरण बनाने की कोशिश करूंगा। मान लें कि मेरे पास यह है:सुनिश्चित नहीं है कि एक अमूर्त संपत्ति का उपयोग कब करें और

abstract class Human 
{ 
    public GenderType Gender { get; set; } 
    public string Name { get; set; } 
    public Date Born { get; set; } 
    public bool IsNerd { get; set; } 

    abstract public void Speak(); 
    abstract public void Sleep(); 
    abstract public void AnoyingPeopleOnStackOverflow(); 
    //... so on 
} 

class Peter : Human 
{ 
    //Peter is special, he got a second name 
    //But thats all, everything else is the same as like on other humans 
    public string SecondName { get; set; } 

    //...override abstract stuff 
} 

क्या यह ठीक है? जैसा कि मैंने समझा, मुझे एक अमूर्त संपत्ति का उपयोग करने की ज़रूरत नहीं है अगर मैं इसे ओवरराइड नहीं करना चाहता हूं। और इस स्थिति में यह ठीक रहेगा, बस Speak, Sleep जैसी विधियां और इसी तरह सार होना चाहिए।

अब, यदि यह ठीक है, तो मुझे कब एक अमूर्त संपत्ति का उपयोग करना चाहिए या नहीं?

+1

"जब मैं एक अमूर्त संपत्ति का उपयोग कब करूं या कब करना चाहिए" --- जब आप यह कहना चाहते हैं कि उस बच्चे वर्ग को एक विशिष्ट विधि कार्यान्वयन प्रदान करना है – zerkms

+1

1) यदि यह जावा था, तो शायद कोई समस्या नहीं होगी। आप शायद एक "इंटरफ़ेस" का उपयोग करेंगे। यह अनिवार्य रूप से आप सी # में क्या कर रहे हैं, है ना?2) मेरी व्यक्तिगत भावना यह है कि अगर इसे "अनुबंध" का हिस्सा बनने की आवश्यकता है, तो इसे अपने अमूर्त वर्ग में घोषित करना उचित है। दूसरे शब्दों में, मुझे लगता है कि आपने जो किया है वह बिल्कुल ठीक है। IMHO ... – paulsm4

+1

@ paulsm4 आप सी # के साथ भी ऐसा कर सकते हैं। –

उत्तर

56

जब आपके पास कोई डिफ़ॉल्ट कार्यान्वयन नहीं होता है और जब व्युत्पन्न कक्षाओं को इसे कार्यान्वित किया जाना चाहिए तो एक अमूर्त संपत्ति का उपयोग करें।

जब आप बेस क्लास में कार्यान्वयन करते हैं तो वर्चुअल प्रॉपर्टी का उपयोग करें लेकिन ओवरराइडिंग की अनुमति देना चाहते हैं।

किसी सदस्य को ओवरराइड करने के लिए override कीवर्ड का उपयोग करें। सदस्य को sealed override के रूप में चिह्नित करें यदि इसे फिर से ओवरराइड नहीं किया जाना चाहिए।

संपत्ति को abstract या virtual के रूप में चिह्नित न करें अगर आप इसे ओवरराइड नहीं करना चाहते हैं।

गैर-सार, गैर-आभासी सदस्य को छुपाने के लिए new कीवर्ड का उपयोग करें (यह शायद ही कभी एक अच्छा विचार है)।

How to: Define Abstract Properties

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

देखें:

व्यक्तिगत रूप से, मुझे लगता है कि मैं सार तरीकों अक्सर उपयोग लेकिन सार गुण शायद ही कभी।

4

विधि का उपयोग करें जब सभी उप-वर्ग में विधि/संपत्ति को लागू करने के लिए है। यदि इसे लागू करने के लिए प्रत्येक उप-वर्ग की आवश्यकता नहीं है, तो इसका उपयोग न करें।

आपके उदाहरण के लिए, यदि प्रत्येक व्यक्ति के लिए SecondName आवश्यक नहीं है, तो बेस क्लास में एक सार संपत्ति बनाने की आवश्यकता नहीं है। अगर दूसरी तरफ, प्रत्येक व्यक्ति को दूसरे नाम की आवश्यकता होती है, तो उसे एक अमूर्त संपत्ति बनाएं।

एक अमूर्त संपत्ति का सही उपयोग का उदाहरण: क्योंकि हर कार एक निर्माता है और उपयोगकर्ता के लिए जो कि निर्माता है बताने के लिए सक्षम होने की जरूरत

public class Car 
{ 
    public abstract string Manufacturer { get; } 
} 

public class Odyssey : Car 
{ 
    public override string Manufacturer 
    { 
     get 
     { 
      return "Honda"; 
     } 
    } 
} 

public class Camry : Car 
{ 
    public override string Manufacturer 
    { 
     get 
     { 
      return "Toyota"; 
     } 
    } 
} 

Maker सार बनाना सही है।

1

एक अमूर्त संपत्ति का उपयोग किया जाएगा जहां आप कक्षा को हमेशा संपत्ति का पर्दाफाश करना चाहते हैं, लेकिन जहां आप उस संपत्ति के अपूर्णता को पिन नहीं कर सकते हैं - इसे ऐसा करने के लिए विरासत वर्ग को मजबूर/मजबूर कर दिया जाता है।

एक उदाहरण here है, जहां अमूर्त वर्ग का नाम Shape रखा गया है, और यह एक सार Area संपत्ति का खुलासा करता है। आप बेस क्लास में Area संपत्ति को लागू नहीं कर सकते हैं, क्योंकि क्षेत्र के सूत्र प्रत्येक प्रकार के आकार के लिए बदल जाएंगे। सभी आकारों में एक क्षेत्र (कुछ प्रकार का) होता है, इसलिए सभी आकारों को संपत्ति का खुलासा करना चाहिए।

आपका कार्यान्वयन स्वयं ठीक दिखता है। Human के लिए एक अमूर्त संपत्ति के एक समझदार उदाहरण के बारे में सोचने की कोशिश कर रहा था, लेकिन कुछ भी उचित नहीं सोच सका।

11

सार सदस्य केवल आभासी सदस्य हैं जिन्हें आपको ओवरराइड करना है। आप इसे किसी ऐसे चीज़ के लिए उपयोग करते हैं जिसे कार्यान्वित किया जाना है, लेकिन बेस क्लास में लागू नहीं किया जा सकता है।

यदि आप एक आभासी संपत्ति बनाना चाहते हैं, और चाहते हैं कि इसे कक्षा में उत्तराधिकारी होना चाहिए, तो आप इसे एक सार संपत्ति बना देंगे।

आप उदाहरण के लिए एक जानवर वर्ग है, साँस लेने के लिए अपनी क्षमता नहीं संभव जानकारी है कि यह एक जानवर है से सिर्फ detemine को होगा, लेकिन यह कुछ है कि बहुत महत्वपूर्ण है है:

public abstract class Animal { 

    public abstract bool CanBreathe { get; } 

} 

एक मछली के लिए और एक कुत्ता कार्यान्वयन अलग होगा:

public class Dog : Animal { 

    public override bool CanBreathe { get { return !IsUnderWater; } } 

} 

public class Fish : Animal { 

    public override bool CanBreathe { get { return IsUnderWater; } } 

} 
26

मुझे पता है कि मैं उन्हें क्या करना चाहता हूं, मुझे परवाह नहीं है कि वे इसे कैसे करते हैं: इंटरफ़ेस।

मुझे पता है कि मैं उन्हें क्या करना चाहता हूं, मुझे परवाह नहीं है कि वे इसमें से कुछ कैसे करते हैं, लेकिन मेरे पास दृढ़ विचार हैं कि वे कैसे (या कम से कम उनमें से अधिकतर) अन्य बिट्स करेंगे: सार कक्षा ।

मुझे पता है कि मैं उन्हें क्या करना चाहता हूं, और उनमें से अधिकतर इसे कैसे करेंगे: वर्चुअल सदस्यों के साथ कंक्रीट क्लास।

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

(संयोग से, मैं पीटर को मानव के प्रकार के रूप में नहीं सोचूंगा, लेकिन प्रत्येक पीटर के रूप में मनुष्य के उदाहरण के रूप में पीटर को कहा जाता है। इस तरह से उदाहरण कोड को चुनना वाकई उचित नहीं है, लेकिन जब आप इस तरह के मुद्दे के बारे में सोच रहे हैं तो यह सामान्य से अधिक प्रासंगिक है)।

+3

+1 - सहमत हैं, 'पीटर' को 'मानव' के उप-वर्ग का उदाहरण होना चाहिए, उदा। 'HumansWithTwoNames' –

+2

@TimMedora हाँ, और हम सभी उदाहरण कोड बनाते समय बुरे नामों के बारे में सोचते हैं, और यह सामान्य रूप से कोई फर्क नहीं पड़ता, लेकिन यह एक प्रश्न है जहां यह अधिक से अधिक मायने रखता है। –

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