उन कार्यों का उदाहरण दें जो जावा में ओवरलोडिंग और ओवरराइडिंग दोनों के मामलों में सह-अस्तित्व और विरोधाभासी प्रदर्शित करते हैं? [बन्द है]


105

कृपया जावा में सहसंयोजक और विरोधाभासी के लिए एक अच्छा उदाहरण दिखाएं।

जवाबों:


155

सहप्रसरण:

class Super {
  Object getSomething(){}
}
class Sub extends Super {
  String getSomething() {}
}

सब # getSomething कोवेरिएंट है क्योंकि यह सुपर # getSomething के रिटर्न प्रकार का एक उपवर्ग देता है (लेकिन Super.getSomething () के अनुबंध को पूर्ण करता है)

contravariance

class Super{
  void doSomething(String parameter)
}
class Sub extends Super{
  void doSomething(Object parameter)
}

उप # doSomething विरोधाभासी है क्योंकि यह Super # doSomething (लेकिन फिर, Super # doSomething के अनुबंध को पूरा करता है) के पैरामीटर के एक सुपरक्लास का पैरामीटर लेता है

सूचना: यह उदाहरण जावा में काम नहीं करता है। जावा संकलक अधिभार और doSomething () - विधि को ओवरराइड नहीं करेगा। अन्य भाषाएँ विरोधाभासी इस शैली का समर्थन करती हैं।

जेनेरिक्स

जेनरिक के लिए भी यह संभव है:

List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;

अब आप सभी तरीकों का उपयोग कर सकते हैं, covariantListजेनेरिक पैरामीटर नहीं लेते हैं (जैसा कि कुछ "ऑब्जेक्ट का विस्तार" होना चाहिए), लेकिन गेटर्स ठीक काम करेंगे (जैसा कि लौटी हुई वस्तु हमेशा "ऑब्जेक्ट" प्रकार की होगी)

इसके विपरीत यह सच है contravariantList: आप सभी तरीकों को जेनेरिक मापदंडों के साथ एक्सेस कर सकते हैं (आप जानते हैं कि यह "स्ट्रिंग" का सुपरक्लास होना चाहिए, ताकि आप हमेशा एक पास कर सकें), लेकिन कोई भी गेटर्स (लौटा हुआ प्रकार स्ट्रिंग के किसी अन्य सुपरटेप का नहीं हो सकता है) )


79
Contravariance का पहला उदाहरण जावा में काम नहीं करता है। doSomething () सब क्लास में ओवरलोड होता है, ओवरराइड नहीं।
क्रेग पी। मोटलिन

15
वास्तव में। जावा उपप्रकार में विरोधाभासी तर्कों का समर्थन नहीं करता है। केवल कोवेरियन किस चिंता पद्धति के प्रकारों के लिए (जैसे पहले उदाहरण में)।
the_dark_destructor

बहुत बढ़िया जवाब। Covariance मेरे लिए तर्कसंगत लगता है। लेकिन क्या आप मुझे जेएलएस में एक पैराग्राफ बता सकते हैं जो कंट्रोवर्सी का वर्णन करता है? Sub.doSomething क्यों आमंत्रित किया गया है?
मिखाइल

2
जैसा कि क्रेग ने बताया, यह नहीं है। मुझे लगता है कि यहां ओवरराइडिंग और ओवरलोडिंग के बीच टकराव होता है और SUN ने हमेशा की तरह पिछड़े-संगत विकल्प का चयन किया। तो जावा में आप किसी विधि को ओवरराइड करते समय कंट्रोवर्न्ट मापदंडों का उपयोग नहीं कर सकते हैं।
हार्डकोडेड

1
मुझे यह जानकर अच्छा लगा कि मुझे अपने उत्तर के लिए निराशा क्यों हुई।
हार्डकोड

48

सह-विचरण: Iterable and Iterator। यह लगभग हमेशा एक सह-संस्करण Iterableया परिभाषित करने के लिए समझ में आता है IteratorIterator<? extends T>बस के रूप में इस्तेमाल किया जा सकता है Iterator<T>- एक ही स्थान जहां टाइप पैरामीटर दिखाई देता है nextविधि से वापसी प्रकार है , इसलिए इसे सुरक्षित रूप से अप-कास्ट किया जा सकता है T। लेकिन अगर आपके पास Sविस्तार है T, तो आप Iterator<S>एक प्रकार के चर को भी असाइन कर सकते हैं Iterator<? extends T>। उदाहरण के लिए यदि आप खोज विधि को परिभाषित कर रहे हैं:

boolean find(Iterable<Object> where, Object what)

आप इसे कॉल नहीं कर पाएंगे List<Integer>और 5इसलिए इसे बेहतर तरीके से परिभाषित किया जाएगा

boolean find(Iterable<?> where, Object what)

कंट्रा-विचरण: तुलनित्र। यह लगभग हमेशा उपयोग करने के लिए समझ में आता है Comparator<? super T>, क्योंकि यह बस के रूप में इस्तेमाल किया जा सकता है Comparator<T>। प्रकार पैरामीटर केवल compareविधि पैरामीटर प्रकार के रूप में प्रकट होता है , इसलिए Tइसे सुरक्षित रूप से पारित किया जा सकता है। उदाहरण के लिए यदि आपके पास एक है DateComparator implements Comparator<java.util.Date> { ... }और आप List<java.sql.Date>उस तुलनित्र ( java.sql.Dateएक उप-वर्ग java.util.Date) के साथ छांटना चाहते हैं , तो आप इसके साथ कर सकते हैं:

<T> void sort(List<T> what, Comparator<? super T> how)

लेकिन साथ नहीं

<T> void sort(List<T> what, Comparator<T> how)

-4

को देखो Liskov प्रतिस्थापन सिद्धांत । वास्तव में, यदि क्लास बी क्लास ए का विस्तार करता है तो आपको ए की आवश्यकता होने पर बी का उपयोग करने में सक्षम होना चाहिए।


6
यह सवाल का जवाब नहीं दे रहा है और भ्रामक है। यह पूरी तरह से एक वैरिएंट सिस्टम को डिजाइन करना संभव होगा जो अर्थ संबंधी शुद्धता को तोड़ता है और इसलिए एलएसपी का उल्लंघन करता है।
मैट व्हिपल

यह contra variantकहने का मामला नहीं है । super.doSomething("String")द्वारा प्रतिस्थापित नहीं किया जा सकता है sub.doSomething(Object)
zinking

यह सवाल नहीं है
ओलिविएरट्रिएन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.