2015-12-09 13 views
19

के बीच अंतर मैं नीचे दो कोड स्निपेट के बीच अंतर को समझ नहीं सकता। क्या कोई मुझे सरल स्पष्टीकरण के साथ मदद कर सकता है?जेनेरिक सुपर क्लास और सुपर क्लास प्रकार

सबसे पहले, मुझे यह कहना है कि मेरे पास बहुत से वर्ग हैं जो BaseEntity नामक एक सुपर क्लास का विस्तार करते हैं, तो निम्नलिखित स्निपेट के अंतर, लाभ और कमी क्या हैं?

// 1 
public <T extends BaseEntity> T getName(T t) { 
    return t; 
} 

// 2 
public BaseEntity getName(BaseEntity t) { 
    return t; 
} 

उत्तर

24

पहला स्निपेट अधिक लचीला है क्योंकि यह वास्तविक प्रकार T को संरक्षित करता है। यदि आप एक उपवर्ग है मान लीजिए:

class SubEntity extends BaseEntity {} 

पहले मामले में आप लिख सकते हैं:

SubEntity result = getName(new SubEntity()); 

लेकिन दूसरे मामले में आप एक डाली की आवश्यकता होगी:

SubEntity result = (SubEntity)getName(new SubEntity()); 
1

1) अपने पहले कोड में आप वापसी विधि का एक प्रतिबंध BaseEntity की subclasses होना चाहिए और इनपुट परम BaseEntity का एक ही उपवर्ग होना चाहिए है।

2) आपके दूसरे कोड में आपके पास BaseEntity होना चाहिए।

+0

यह सच नहीं है। पहले कोड स्निपेट में, इनपुट पैरामीटर का प्रकार 'बेसएन्टीटी' का वही सबक्लास होना चाहिए जो 'रिटर्न' मान के रूप में हो। यह किसी भी प्रकार का ऑब्जेक्ट नहीं हो सकता है।दूसरे स्निपेट में, 'वापसी' मान और इनपुट पैरामीटर' बेसएन्टीटी 'के उप-वर्ग भी हो सकते हैं। – Daniel

7

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

मान लीजिए कि आप करते हैं:

MyEntity myEntity = ... 
MyEntity entity = getName(myEntity); 

दूसरी विधि के साथ लिखने के लिए होता है जबकि:

public class MyEntity extends BaseEntity { 
} 
पहली विधि आप की तरह कुछ हो सकता है के साथ

MyEntity entity = (MyEntity)getName(myEntity); 

ऐसा इसलिए है क्योंकि आप अपनी पहली विधि में ठोस प्रकार निर्दिष्ट करते हैं।

4

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

आपका पहला विधि घोषणा कि वापसी प्रकार दिया गया तर्क के रूप में एक ही प्रकार हो की आवश्यकता है। तो

public <T extends BaseEntity> T getName(T t) { 
    return new SubEntity(); // Where SubEntity extends BaseEntity 
} 

संकलित करने के लिए, जबकि

public BaseEntity getName(BaseEntity t) { 
    return new SubEntity(); // Where SubEntity extends BaseEntity 
} 

भले ही पूरी तरह से कानूनी है विफल रहता है BaseEntity विधि में पारित SubEntity से एक पूरी तरह से अलग प्रकार है।

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