2013-07-30 4 views
14

मुझे इस समस्या को हल करने के लिए एक शानदार तरीका नहीं मिला है। मेरे पास एक अमूर्त वर्ग है कि कई अन्य वर्ग एक अमूर्त विधि के साथ विरासत में हैं जो अलग-अलग प्रकार के शून्य से 4-5 तर्कों में कहीं भी हो सकते हैं।तर्कों की परिवर्तनीय सूची के साथ सार विधि

public abstract class Item { 
public abstract void use(); 
} 

उदाहरण के लिए, मैं एक पुस्तक वर्ग है कि इस विरासत और जब उपयोग(), मैं एक कुंजी वर्ग कि विरासत और एक स्ट्रिंग और एक कतार तर्कों के रूप जब अधिभावी, आदि लगता है अधिभावी कोई तर्क लेता है ..

मैंने जेनेरिक का उपयोग करने की कोशिश की है, लेकिन मुझे आइटम पर इस्तेमाल होने वाली संख्या को इनपुट करना होगा, जब यह वास्तव में कक्षा पर निर्भर करता है।

public abstract class Item<T,U> { 
public abstract void use(T arg1, U arg2); //Number of arguments/types could be more or less 
} 

मैं वस्तुओं की एक चर सूची भेजने की कोशिश की है लेकिन वस्तु प्रकार हमेशा परिवर्तनशील हैं और मैं वाक्य रचना के रूप में अनिश्चित है इनहेरिट कक्षाओं में प्राप्त करने के लिए।

public abstract class Item<T> { 
public abstract void use(T... arguments); 
} 

public class Book extends Item<?> { 
public void use(?); 
} 

public class Book extends Item<String, Queue> { //Wrong number of arguments since I can't use Item<T...> 
public void use(String str, Queue q); //fails 
} 

मैं कुछ गलत कर रहा हूं - क्या कोई भी सहायता या अंतर्दृष्टि प्रदान कर सकता है?

+0

यदि आप 'आइटम इसे = नई पुस्तक(); 'करते हैं, तो आप' बुक.यूज (स्ट्रिंग, कतार) विधि को कॉल करने का प्रस्ताव कैसे देते हैं; 'यदि संकलक को यह नहीं पता कि सही तर्क प्रकार क्या हैं ? और यदि आप माता-पिता वर्ग के चर में 'आइटम' का उप-वर्ग नहीं होने की अपेक्षा करते हैं, तो विधि को सार तत्व क्यों होना चाहिए? – millimoose

उत्तर

12

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

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

public class UseParameters { 
    private String string; 
    private Queue queue; 
    // Any other potential parameters to use(...) 

    public void setString(String string) { 
     this.string = string; 
    } 

    public String getString() { 
     return string; 
    } 

    // All of the other accessor methods, etc. 
} 

उसके बाद, आप इस तरह मद में उपयोग विधि निर्धारित कर सकते हैं:

public abstract void use(UseParameters params); 

और एक मद का उपयोग कर किसी भी कोड वस्तु उचित रूप से की पैरामीटर सेट करने के लिए होगा:

Item item = // However you're going to get the item 
UseParameters params = new UseParameters(); 
params.setString("good string"); 
params.setQueue(new Queue()); 
item.use(params); 

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

@Override 
public void use(UseParameters params) { 
    if(params.getString == null || params.getQueue() == null) 
     // throw exception 

    // Do what books do with strings and queues 
} 

मुझे लगता है कि आप हो जाता है कि आप क्या चाहते लगता है, लेकिन आप रिफैक्टरिंग पर विचार करना चाहिए, मुझे लगता है।

+0

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

5

यदि तर्क के रूप में उपयोग किए जाने वाले प्रकार हमेशा परिवर्तनीय होते हैं तो मुझे जेनेरिक का उपयोग करने का कोई कारण नहीं दिखता है। बस सादा ऑब्जेक्ट प्रकार का उपयोग करें:

public abstract class Item { 
    public abstract void use(Object ... arguments); 
} 

public class Book extends Item { 
    public void use(Object ... arguments) { ... } 
} 
1

सबसे अच्छा तरीका मैं सोच सकता हूं कि वस्तुओं को उनके use() विधि के व्यवहार के अनुसार समूहबद्ध करना है।

उदाहरण

public abstract class QueueableItem { 
    public abstract void use(String, Queue); 
} 

public abstract class OrdinaryItem{ 
    public abstract void use(String); 
} 

वर्गीकृत किया आइटम एक आम व्यवहार (एक ही विधि हस्ताक्षर & वापसी मान में के रूप में आम) का हिस्सा हैं, तो आप को परिभाषित करने और एक माता पिता के वर्ग है कि इस आम की परिभाषा में शामिल होंगे विस्तार कर सकते हैं व्यवहार।

8

तुम क्या चाहते Value Object Pattern है।

एक वर्ग को परिभाषित करें जो विभिन्न पैरामीटर प्रकारों को एक मान ऑब्जेक्ट में समाहित करता है, और सार विधि इस प्रकार के पैरामीटर को स्वीकार करती है। आप जिन पैरामीटर पर विचार कर रहे थे उनमें से प्रत्येक भिन्नता का अपना मूल्य वर्ग होगा।

तो बस एक सामान्य प्रकार वर्ग को जोड़ने के लिए और सार विधि है उस प्रकार के पैरामीटर स्वीकार करते हैं:

public class MyItem extends Item<MyValueClass> { 
    public void use(MyValueClass v) { 
    } 
} 
:

public abstract class Item<V> { 
    public abstract void use(V v); 
} 

इसका इस्तेमाल करने के लिए, मान लीजिए MyItem प्रकार MyValueClass के एक मूल्य वस्तु की जरूरत है

0

हां, हम अमूर्त विधि को पैरामीटर प्रदान कर सकते हैं लेकिन व्युत्पन्न कक्षाओं में लिखे गए लागू तरीकों के लिए समान प्रकार के पैरामीटर प्रदान करना आवश्यक है।

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