2010-04-20 19 views
5

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

Sim वस्तु सिमुलेशन संस्थाओं के लिए पहुँच प्रदान करता है और सिम (शुरू/रोकें/बंद)

Scenario वस्तु आप अनुकरण संस्थाओं के साथ सिम को भरने के लिए अनुमति देता है नियंत्रित करता है।

सिम:

public class Sim 
{ 
    public <T extends Sim> void loadScenario(Scenario<T> scenario) 
    { 
     reset(); 
     scenario.load(this); 
    } 
} 

परिदृश्य:

public interface Scenario<T extends Sim> 
{ 
    public void load(T sim); 
} 

लक्ष्य है उन बनाने के लिए एक MySim कि extends Sim अनुमति देते हैं और एक MyScenario कि implements Scenario<MySim> अपने डोमेन के लिए करने के लिए।

उदा। MyScenario:

public class MyScenario<MySim> 
{ 
    public void load(MySim sim) 
    { 
     // make calls to sim.addMySimEntity(...) 
    } 
} 

विशेष रूप से, ऊपर कोड का उपयोग कर, Sim.loadScenario में scenario.load(this) कॉल मुझे त्रुटि देता है: विधि लोड (टी) प्रकार परिदृश्य में तर्क (सिम) के लिए लागू नहीं है। मैं समझता हूं क्योंकि यह this (जो कि Sim प्रकार है) T extends Sim है जिसका मतलब है कि किसी भी तरह से मुझे किसी ऑब्जेक्ट में गुजरना चाहिए जो सिम का कोई सबटाइप हो सकता है।

मैं जो हासिल करना चाहता हूं उसे प्राप्त करने के लिए इस मुद्दे को सुधारने का तरीका क्या है? या, क्या यह भी संभव है? शायद जेनेरिक मेरे लिए ऐसा नहीं कर सकते हैं।

+0

मुझे लगता है कि यह सर्कुलर जेनेरिक संदर्भों के बारे में पूछे गए एक प्रश्न से संबंधित हो सकता है: http://stackoverflow.com/questions/2567595/creating-circular-generic-references –

उत्तर

6

यदि यह हमेशा सिम का एक उप प्रकार बनने जा रहा है तो क्यों न केवल अपनी विधि में निर्दिष्ट करें और इसके साथ किया जाए? ऐसा लगता है कि जेनेरिक आपको यहां बहुत ज्यादा खरीद रहा है।

लेकिन वैसे भी, मुझे लगता है कि आप loadScenario होना चाहते हैं:

public void loadScenario(Scenario<? extends Sim> scenario) 

संपादित करें: ठीक है अब मैं वास्तव में इसके बारे में सोचा, कि या तो काम नहीं करेगा। आपका लोडसेनारियो एक प्रकार पैरामीटर टी के साथ एक परिदृश्य पारित करने जा रहा है जो कि सिम का एक उप प्रकार है। लेकिन आप इसे एक सिम पास करने की कोशिश कर रहे हैं जिसमें सिम के सही उप प्रकार होने की कोई गारंटी नहीं है।

समाधान Scenario.load विधि एक सिम अर्थात लेने की जरूरत है:

public interface Scenario<T extends Sim> 
{ 
    public void load(Sim sim); 
} 

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

संपादित करें:

public class Sim 
{ 
    public static <T extends Sim> void loadScenario(Scenario<T> scenario, T sim) 
    { 
     scenario.load(sim); 
    } 
} 

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

+0

निश्चित रूप से आपका मतलब है 'लोड (टी सिम)' में आखिरी मामला? अन्यथा वर्ग पर जेनेरिक पैरामीटर उपयोगी से कम है ... :-) –

+0

@Andrzej नहीं, मेरा मानना ​​है कि उसका मतलब लोड (सिम सिम) था। दरअसल, वर्ग पर जेनेरिक अब उपयोगी नहीं है। ऐसा लगता है कि मैं जो करना चाहता हूं उसे पूरा करने में सक्षम नहीं हूं। – Brad

+0

@Andrzej और @Brad। सही, सामान्य यह उपयोगी नहीं है जो टिप्पणी के पहले भाग का बिंदु था :-) सामान्य बहुरूपता यहां प्रभावी होनी चाहिए। –

2

I understand this is because I'm loading this (which is of type Sim) when what is required is T extends Sim which means somehow I should be passing in an object that can be any subtype of Sim.

समस्या नहीं। उस विधि कल्पना करने के लिए accoding, आप वर्ग T की एक वस्तु है, जो विशिष्ट उपवर्ग Sim की अपने परिदृश्य मिलान है गुजर जाना चाहिए - (कम से कम जो this नहीं है कि कोड गारंटी नहीं दे सकता कि यह है)।

यह सुनिश्चित नहीं है कि इसे कैसे ठीक किया जाए।

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