2011-09-28 18 views
8

मेरे पास सिस्टम का एक गुच्छा है, उन्हें A, B, C, D, E, F, G, H, I, J पर कॉल करने दें।इंटरफेस, सार, या सिर्फ आभासी तरीकों?

उनके सभी समान तरीके और गुण हैं। कुछ में सटीक वही विधि और गुण होते हैं, कुछ थोड़ा भिन्न हो सकते हैं और कुछ बहुत भिन्न हो सकते हैं। अभी, मेरे पास प्रत्येक सिस्टम के लिए बहुत अधिक डुप्लिकेट कोड है। उदाहरण के लिए, मेरे पास GetPropertyInformation() नामक एक विधि है जिसे प्रत्येक सिस्टम के लिए परिभाषित किया गया है। मैं यह पता लगाने की जो विधि सबसे अच्छा तरीका डुप्लिकेट कोड या शायद नीचे दिए गए तरीकों में से एक कम करने के लिए किया जाएगा कोशिश कर रहा हूँ जाने का रास्ता नहीं है:

इंटरफ़ेस

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public class A : ISystem 
{ 
    public void GetPropertyInformation() 
    { 
     //Code here 
    } 
} 

सार

एक सुपर बेस कक्षा में
public abstract class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //B specific code here 
    } 
} 

वर्चुअल तरीके

public class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
    //System Code 
    } 
} 

public class C : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //C Code 
    } 
} 

एक सवाल है, हालांकि यह बेवकूफ हो सकता है,, मान लेते हैं मैं सार दृष्टिकोण के साथ चला गया और मैं GetPropertyInformation ओवरराइड करने के लिए करना चाहता था, लेकिन मैं इसे एक अतिरिक्त पैरामीटर दी जाने वाली आवश्यक जाने है यह संभव है या मैं करने के लिए होगा अमूर्त वर्ग में एक और विधि बनाएँ? उदाहरण के लिए, GetPropertyInformation(x)

उत्तर

6

आपका अमूर्त और 'सुपर आधार वर्ग' दृष्टिकोण बहुत अलग नहीं हैं। आपको हमेशा बेस क्लास सार बनाना चाहिए, और आप एक डिफ़ॉल्ट कार्यान्वयन (वर्चुअल विधियों) या नहीं (सार विधियों) प्रदान कर सकते हैं। निर्णायक कारक यह है कि क्या आप कभी भी बेस क्लास के उदाहरण चाहते हैं, मुझे नहीं लगता।

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

ए, बी, सी कक्षाओं स्वाभाविक रूप से एक 'परिवार' से संबंधित नहीं है, तो एक अंतरफलक का उपयोग करें।

और System इतना अच्छा नाम नहीं है।

और जब अधिभावी आप parameterlist नहीं बदल सकते। हो सकता है कि डिफ़ॉल्ट पैरामीटर मदद कर सकें, अन्यथा आपको GetPropertyInformation() के लिए केवल 2 ओवरलोड की आवश्यकता है।

+0

मुझे लगता है कि अमूर्त और सुपर बेस क्लास समान थे। ए, बी, सी सिस्टम में एक मजबूत युग्मन है। एक उद्योग मानक है, लेकिन इसका पालन नहीं किया जाना चाहिए, इसलिए प्रत्येक व्यक्ति या तो मानक को अपना सकता है या मानक को अपने फिटिंग में बदल सकता है। जल्दबाजी में, मैंने सिस्टम उठाया :) – Xaisoft

+0

रास्ते से अच्छे अंक। – Xaisoft

3

आम तौर पर आप वस्तु विरासत जब आप कार्यान्वयन को साझा करने और कम करने के लिए क्या अन्यथा दोहराव होगा करना चाहते हैं। अन्यथा इंटरफेस जीतते हैं क्योंकि वे अधिक लचीले होते हैं क्योंकि सामान्य बेस क्लास की आवश्यकता नहीं होती है।

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

+0

यह "संभव" है - आपको ऐसी विधि घोषित करने में सक्षम होना चाहिए, यह अब मूल विधि का ओवरराइड नहीं है। – millimoose

+2

@ एसआईआई यह निश्चित रूप से संभव नहीं है। सवाल * * विधि को ओवरराइड करने और पैरामीटर जोड़ने के लिए कहा गया। ऐसा नहीं किया जा सकता है। –

+0

मुझे एहसास हुआ कि यह नहीं किया जा सका, इच्छापूर्ण सोच। – Xaisoft

3

मैं कुछ जो मैंने नीचे जोड़ा है उसके साथ जाऊंगा। आपको अभी भी इंटरफ़ेस अनुबंध और साझा कार्यान्वयन का लाभ मिलता है।

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public abstract class System : ISystem 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public string ExtendedSystemProp {get;set;} 

    public override void GetPropertyInformation() 
    { 
     base.GetPropertyInformation(); 

     var prop = "some extra calculating"; 

     GetExtraPropertyInformation(prop); 
    } 

    public void GetExtraPropertyInformation(string prop) 
    { 
     ExtendedSystemProp = prop; 
    } 
} 

ISystem genericSystem = new B(); 
genericSystem.GetPropertyInformation(); 

(genericSystem as B).ExtendedSystemProp = "value"; 
+0

क्या आप इस दृष्टिकोण को विस्तारित कर सकते हैं कि आप इस दृष्टिकोण को क्यों करेंगे? – Xaisoft

+0

इस तरह, आप अभी भी अपनी सभी संपत्तियां प्राप्त करते हैं, भले ही आप केवल 'आईसिस्टम' इंटरफेस के साथ प्रोग्रामिंग कर रहे हों (जो आपको उनके पास करना चाहिए)। हालांकि, यदि आप किसी संदर्भ में कोडिंग कर रहे हैं जहां केवल बी मौजूद है: 'बी बी सिस्टम = नया बी();' आप स्पष्ट उपयोग के लिए 'बी' विशिष्ट विधि का भी खुलासा करते हैं। – scottm

2

आप ओवरराइड में अतिरिक्त पैरामीटर पास नहीं कर सकते हैं। जब आप ओवरराइड कर रहे हैं, तो आप सटीक हस्ताक्षर के साथ विधि को ओवरराइड कर रहे हैं। मैं सुझाव दूंगा कि आप एक इंटरफ़ेस पैरामीटर जैसे IPropertyInformation में पारित करें जो प्रति कार्यान्वयन को बदल सकता है।

आधारभूत कक्षा या आपके कार्यान्वयन के लिए इंटरफ़ेस के साथ जाने का निर्णय वास्तव में आपके उपयोग पर निर्भर करता है। क्या A-I एक दूसरे के साथ आम बात है कि उन्हें वास्तव में एक ही बेस क्लास से प्राप्त होना चाहिए? यदि ऐसा है, तो बेस क्लास का उपयोग करें। क्या यह वास्तव में है कि सिर्फ GetPropertyInformation साझा किया गया है और अन्यथा सिस्टम पूरी तरह से कार्यात्मक हैं? फिर आप वास्तव में उन्हें एक इंटरफ़ेस साझा करना चाहते हैं।

2

दूसरों ने मूल रूप से मेरे उत्तर में जो कवर किया था, लेकिन "पैरामीटर जोड़ना" बिंदु के बारे में बताया है: यह न भूलें कि नवीनतम सी # आपको विधियों में वैकल्पिक पैरामीटर भी देता है।

+0

लेकिन मुझे बहुत शुरुआत में वैकल्पिक पैरामीटर घोषित करना होगा। मुझे नहीं पता कि मुझे सड़क से 1 वर्ष तक पैरामीटर की आवश्यकता है, इसलिए वैकल्पिक पैरामीटर मुझे उस मामले में अच्छा नहीं करते हैं। – Xaisoft

2

जब तक आपके पास कोई अनिवार्य कारण नहीं है, तो मैं इंटरफ़ेस के साथ जाऊंगा। सार्वजनिक आभासी तरीकों, हालांकि बहुत कुछ किया गया है, not ideal है।

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