2009-06-10 14 views
240

मुझे आश्चर्य है कि टाइपरामीटर की सीमाओं को परिभाषित करने के लिए हमेशा "implements" के बजाय "extends" का उपयोग करने के लिए जावा में एक विशेष कारण है।जावा जेनरिक - क्यों "टी बढ़ाता है" की अनुमति है लेकिन "टी लागू नहीं करता"?

उदाहरण:

public interface C {} 
public class A<B implements C>{} 

निषिद्ध है लेकिन

public class A<B extends C>{} 

सही है। उसका क्या कारण है?

+44

कृपया उत्तर के रूप में Tetsujin no Oni द्वारा उत्तर को चिह्नित करें। – KomodoDave

+5

मुझे नहीं पता कि लोग क्यों सोचते हैं कि Tetsujin नो Oni द्वारा जवाब वास्तव में सवाल का जवाब है। यह मूल रूप से अकादमिक शब्द का उपयोग करके ओपी के अवलोकनों को दोहराता है, लेकिन कोई तर्क नहीं देता है। "कोई 'उपकरण' क्यों नहीं है?" - "क्योंकि केवल 'विस्तार' है। – ThomasR

+1

थॉमसआर: ऐसा इसलिए है क्योंकि यह "अनुमत" का सवाल नहीं है, लेकिन इसका अर्थ यह है कि इस बात का कोई फर्क नहीं पड़ता कि आप किसी प्रकार के सामान्य उपभोग को एक बाधा के साथ कैसे लिखेंगे, चाहे बाधा एक इंटरफ़ेस या पूर्वजों के प्रकार से हो। –

उत्तर

287

कक्षा 'उपकरण' या 'विस्तार' के बीच सामान्य बाधा भाषा में कोई अर्थपूर्ण अंतर नहीं है। बाधा संभावनाएं 'विस्तार' और 'सुपर' हैं - यानी, यह वर्ग उस दूसरे (विस्तार) के लिए असाइन करने योग्य है, या यह वर्ग उस (सुपर) से असाइन किया जा सकता है।

+0

@ कोमोडो डेव (मुझे लगता है कि उत्तर के बगल में नंबर सही है, मुझे यकीन नहीं है कि इसे चिह्नित करने का कोई अन्य तरीका है, कभी-कभी अन्य उत्तरों में अतिरिक्त जानकारी हो सकती है - उदाहरण के लिए मुझे एक विशेष समस्या थी जिसे मैं हल नहीं कर सका और Google इसे खोजते समय यहां भेजता है।) @Tetsujin no Oni (क्या स्पष्टीकरण के लिए कुछ कोड का उपयोग करना संभव होगा?) – ntg

+0

@ntg, यह उदाहरणों की तलाश में एक प्रश्न पर एक बहुत अच्छा उदाहरण है - I इस बिंदु पर उत्तर में एम्बेड करने की बजाए टिप्पणी में इसे लिंक करेंगे। http://stackoverflow.com/a/6828257/93922 –

+1

मुझे लगता है कि कम से कम कारण यह है कि मैं एक जेनेरिक होना चाहूंगा जिसमें एक कन्स्ट्रक्टर और विधियां हो सकें जो किसी भी वर्ग को स्वीकार कर सकें जो दोनों बेस क्लास को एक्सक्स्टेंड करता है और इंटरफ़ेस प्रदर्शित करता है एक इंटरफ़ेस का विस्तार करने वाले इंटरफ़ेस न केवल। फिर इंटरफेस की सुरक्षा के लिए जेनरिक परीक्षण का तात्कालिकता है और वास्तविक वर्ग को प्रकार पैरामीटर के रूप में निर्दिष्ट किया गया है। आदर्श रूप में मैं चाहेगा 'वर्ग जेनेरिक <, RenderableT फैली renderable खींचने योग्य लागू करता है droppable, ...> { जेनेरिक (RenderableT toDrag) { एक्स = (खींचने योग्य) toDrag; } } ' कोई समय जांच संकलित करना चाहता है। – peterk

6

यह हो सकता है कि मूल प्रकार एक सामान्य पैरामीटर है, इसलिए वास्तविक प्रकार कक्षा का एक इंटरफ़ेस हो सकता है। पर विचार करें:

class MyGen<T, U extends T> { 

इसके अलावा ग्राहक से कोड परिप्रेक्ष्य इंटरफेस, वर्गों से लगभग अप्रभेद्य हैं, जबकि उप-प्रकार के लिए यह महत्वपूर्ण है।

14

शायद क्योंकि दोनों पक्षों (बी और सी) के लिए केवल प्रकार प्रासंगिक है, कार्यान्वयन नहीं। अपने उदाहरण

public class A<B extends C>{} 

बी में एक अंतरफलक के रूप में अच्छी तरह से हो सकता है। उप-इंटरफेस के साथ-साथ उप-वर्गों को परिभाषित करने के लिए "विस्तार" का उपयोग किया जाता है।

interface IntfSub extends IntfSuper {} 
class ClzSub extends ClzSuper {} 

मैं आमतौर पर के बारे में सोच के रूप में 'उपसुपर तरह है, लेकिन अतिरिक्त क्षमताओं के साथ' 'उप फैली सुपर', और 'CLZ लागू करता INTF' के रूप में 'CLZINTF की एक अहसास है '। आपके उदाहरण में, यह मेल खाता है: बीसी जैसा है, लेकिन अतिरिक्त क्षमताओं के साथ। क्षमताओं को यहां उपलब्ध नहीं है, प्राप्ति नहीं।

+8

पर विचार करें <बी डी एंड ई> विस्तारित करता है। ई एक वर्ग नहीं होना चाहिए। –

7

यहां फैली अनुमति दी है की एक और अधिक शामिल उदाहरण और है संभवतः आप क्या चाहते हैं:

public class A<T1 extends Comparable<T1>>

2

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

लेकिन मुझे लगता है कि implements थोड़ा और अधिक समझ में आएगा। मुझे लगता है कि इससे अधिक संचार होता है कि पैरामीटर प्रकारों को विरासत संबंध में नहीं होना चाहिए, वे प्रकार के उप प्रकार के संबंध में हो सकते हैं।

जावा शब्दावली similar view व्यक्त करती है।

-2

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

24

जवाब here में है:

एक घिरे प्रकार पैरामीटर की घोषणा करने के लिए, प्रकार पैरामीटर का नाम, extends बाद कीवर्ड, जिसके बाद सूची अपने ऊपरी बाध्य [...]। ध्यान दें कि, इस संदर्भ में, विस्तार को सामान्य अर्थ में extends (कक्षाओं में) या implements (इंटरफेस के रूप में) का अर्थ है।

तो आपके पास यह है, यह थोड़ा उलझन में है, और ओरेकल इसे जानता है।

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

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