2009-03-16 10 views
12

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

यहाँ मेरी (कट-डाउन) इंटरफेस हैं:

public abstract class Cart : ICart 
{ 

    private List<CartItem> _cartItems = new List<CartItem>(); 

    public List<CartItem> CartItems 
    { 
     get 
     { 
      return _cartItems; 
     } 
    } 
} 

और मेरे CartItem:

public interface ICart 
{ 
    ... 
    List<ICartItem> CartItems { get; set; } 
} 

public interface ICartItem 
{ 
    int ProductId { get; set; } 
    int Quantity { get; set; } 
} 

और यहाँ मेरी सार कार्ट वर्ग (फिर से, केवल प्रासंगिक लाइनों दिखा रहा है) जो ICart लागू करता है कक्षा जो ICartItem लागू करती है:

public abstract class CartItem : ICartItem 
{ 
    ... 
} 

जब मैं कक्षाओं को संकलित करने का प्रयास करता हूं तो मुझे एक त्रुटि मिलती है aying: 'कार्ट' इंटरफ़ेस सदस्य 'CartItems' लागू नहीं करता है। 'Cart.CartItems' 'ICart.CartItems' को कार्यान्वित नहीं कर सकता है क्योंकि इसमें सिस्टम का मिलान करने वाला रिटर्न प्रकार नहीं है। चयन। जेनरिक। लिस्ट < आईसीएर्टआईटीम >।

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

उत्तर

20

आपको लगता है कि प्राप्त करने के लिए सी # 2 में उपयोगकर्ता जेनरिक की जरूरत है:

public interface ICart<T> where T : ICartItem 
{ 
    // ... 
    List<T> CartItems { get; set; } 
} 

public abstract class Cart : ICart<CartItem> 
{ 
    // ... 
    public List<CartItem> CartItems { get; set; } 
} 
+0

जेनरिक C# 2.0 :) –

+0

यह इस लागू करने के लिए एक बहुत अच्छा तरीका है के रूप में उपलब्ध हैं! – mquander

+0

(सी # 2 चीज तय की गई है; आशा है कि आपको कोई फर्क नहीं पड़ता ...) –

0

ICart CartItems के लिए एक गेटर और सेटर निर्दिष्ट करता है, लेकिन अपने कार्यान्वयन केवल एक बात है।

4

अपनी अमूर्त कक्षा में, आपको यह परिभाषित करना चाहिए कि कार्टइटेम्स संपत्ति का रिटर्न प्रकार List<ICartItem> है।

लेकिन, यदि आप वास्तव में चाहते हैं कि संपत्ति प्रकार List<CartItem> की है, तो आप शायद यह कर सकते हैं:

public interface ICart<TCartItem> where TCartItem : ICartItem 
{ 
    List<TCartItem> CartItems { get; set; } 
} 

public interface ICartItem 
{ 
} 

public abstract class Cart : ICart<CartItem> 
{ 
    public List<CartItem> { get; set; } 
} 

public abstract class CartItem : ICartItem 
{ 
} 
3

यह विपरीत/सहप्रसरण की बात है।

इस संकलन को बनाने के लिए 2 बदलावों की आवश्यकता है।

1) इंटरफ़ेस की संपत्ति पर "सेट" विकल्प निकालें। (यह केवल एक बात को लागू है, संपत्ति है, जो सबसे समझ में आता है, किसी भी मामले में)

2) गाड़ी को इसमें बदलें:

 
public abstract class Cart : ICart 
{

private List<CartItem> _cartItems = new List<CartItem>(); 

public List<ICartItem> CartItems 
{ ... 

मैं भी अत्यधिक बजाय अपने इंटरफेस को बदलने IList का पर्दाफाश करने की सलाह देते हैं सूची। डिज़ाइन दिशानिर्देश (और FxCop) सार्वजनिक इंटरफ़ेस में सूची को उजागर करने की अनुशंसा नहीं करते हैं। सूची एक कार्यान्वयन विस्तार है - IList उपयुक्त इंटरफ़ेस/वापसी प्रकार है।

2

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

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

public interface ICart<T> where T : ICartItem 
{ 
    List<T> CartItems { get; set; } 
} 
0

इसे पूरा करने के 2 तरीके हैं। आप या तो जेनिक्स का उपयोग कर सकते हैं या स्पष्ट रूप से इंटरफेस सदस्यों को लागू कर सकते हैं।

जेनेरिक्स

public interface ICart<TCartItem> where TCartItem : ICartItem 
{ 
    ... 
    List<TCartItem> CartItems { get; set; } 
} 

public interface ICartItem 
{ 
    int ProductId { get; set; } 
    int Quantity { get; set; } 
} 

public abstract class Cart : ICart<CartItem> 
{ 

    private List<CartItem> _cartItems = new List<CartItem>(); 

    public List<CartItem> CartItems 
    { 
     get 
     { 
      return _cartItems; 
     } 
    } 
} 
public abstract class CartItem : ICartItem 
{ 
    ... 
} 

स्पष्ट रूप से कार्यान्वित सदस्यों

public interface ICart 
{ 
    ... 
    List<ICartItem> CartItems { get; set; } 
} 
public interface ICartItem 
{ 
    int ProductId { get; set; } 
    int Quantity { get; set; } 
} 

public abstract class Cart : ICart 
{ 
    private List<CartItem> _cartItems = new List<CartItem>(); 

    List<ICartItem> ICart.CartItems 
    { 
     get 
     { 
      return CartItems; 
     } 
    } 
    public List<CartItem> CartItems 
    { 
     get 
     { 
      return _cartItems; 
     } 
    } 
} 
public abstract class CartItem : ICartItem 
{ 
    ... 
} 
संबंधित मुद्दे