java for कॉन्वर्सिस, Invariance और Contravariance सादे अंग्रेजी में समझाया?



java platform (2)

आज, मैंने जावा में कोविरेन्स, कंट्रावायरिएन्स (और इनवेरिएंस) के बारे में कुछ लेख पढ़े हैं। मैंने अंग्रेजी और जर्मन विकिपीडिया लेख, और आईबीएम से कुछ अन्य ब्लॉग पोस्ट और लेख पढ़े।

लेकिन मैं अभी भी थोड़ा उलझन में हूं कि ये वास्तव में क्या हैं? कुछ कहते हैं कि यह प्रकार और उपप्रकारों के बीच संबंधों के बारे में है, कुछ कहते हैं कि यह प्रकार के रूपांतरण के बारे में है और कुछ कहते हैं कि इसका उपयोग यह तय करने के लिए किया जाता है कि कोई विधि ओवरराइड या अधिभारित है या नहीं।

इसलिए मैं सादे अंग्रेजी में एक आसान स्पष्टीकरण की तलाश में हूं, जो एक शुरुआती दिखाता है कि कोविरिएंस और कंट्रावायरेंस (और Invariance) क्या है। एक आसान उदाहरण के लिए प्लस प्वाइंट।


Answer #1

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

ऊपर के सभी।

दिल में, ये शब्द वर्णन करते हैं कि उप प्रकार के संबंध प्रकार परिवर्तनों से कैसे प्रभावित होते हैं। यही है, यदि A और B प्रकार हैं, तो f एक प्रकार का परिवर्तन है, और ≤ उप प्रकार का संबंध (यानी A ≤ B अर्थ है कि A A ≤ B का उप प्रकार है), हमारे पास है

  • f covariant है अगर A ≤ B तात्पर्य है कि f(A) ≤ f(B)
  • f contravariant है अगर A ≤ B तात्पर्य है कि f(B) ≤ f(A)
  • यदि उपर्युक्त में से कोई भी नहीं है तो f invariant है

आइए एक उदाहरण पर विचार करें। चलो f(A) = List<A> जहां List घोषित की जाती है

class List<T> { ... } 

एफ covariant, contravariant, या invariant है? कॉन्विएन्ट का अर्थ यह होगा कि एक List<String> List<Object> का एक उप प्रकार है, contravariant कि एक List<Object> List<String> का एक उप प्रकार है और invariant है कि न तो दूसरे का उप प्रकार है, यानी List<String> और List<Object> अपरिवर्तनीय प्रकार हैं। जावा में, बाद वाला सत्य है, हम कहते हैं (कुछ हद तक अनौपचारिक रूप से) कि जेनेरिक आविष्कारक हैं।

एक और उदाहरण। चलो चलो (ए) = A[] । एफ covariant, contravariant, या invariant है? यही है, स्ट्रिंग [] ऑब्जेक्ट [], ऑब्जेक्ट [] स्ट्रिंग [] का एक उप प्रकार है, या न तो दूसरे का उप प्रकार है? (उत्तर: जावा में, सरणी covariant हैं)

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

x = y;

टाइपफॉफ़ (वाई) ≤ टाइपऑफ (एक्स) अगर केवल संकलित होगा। यही है, हमने अभी बयान सीखा है

ArrayList<String> strings = new ArrayList<Object>();
ArrayList<Object> objects = new ArrayList<String>();

जावा में संकलित नहीं होगा, लेकिन

Object[] objects = new String[1];

मर्जी।

एक और उदाहरण जहां उप प्रकार संबंध संबंध एक विधि आमंत्रण अभिव्यक्ति है:

result = method(a);

अनौपचारिक रूप से, इस कथन का मूल्यांकन विधि के पहले पैरामीटर के मान को असाइन करके, फिर विधि के शरीर को निष्पादित करके, और फिर result लिए विधियों को वापस लौटाकर मूल्यांकन किया जाता है। आखिरी उदाहरण में सादे असाइनमेंट की तरह, "दाहिने हाथ की ओर" "बाएं हाथ की ओर" का उप-प्रकार होना चाहिए, यानी यह कथन केवल वैध हो सकता है यदि टाइपफ़ो (ए) ≤ टाइपोफ़ (पैरामीटर (विधि)) और वापसी प्रकार ( विधि) ≤ टाइपोफ (परिणाम)। यही है, अगर विधि द्वारा घोषित किया गया है:

Number[] method(ArrayList<Number> list) { ... }

निम्न में से कोई भी अभिव्यक्ति संकलित नहीं करेगा:

Integer[] result = method(new ArrayList<Integer>());
Number[] result = method(new ArrayList<Integer>());
Object[] result = method(new ArrayList<Object>());

परंतु

Number[] result = method(new ArrayList<Number>());
Object[] result = method(new ArrayList<Number>());

मर्जी।

एक और उदाहरण जहां सबटाइपिंग मामलों ओवरराइडिंग है। विचार करें:

Super sup = new Sub();
Number n = sup.method(1);

कहा पे

class Super {
    Number method(Number n) { ... }
}

class Sub extends Super {
    @Override 
    Number method(Number n);
}

अनौपचारिक रूप से, रनटाइम इसे फिर से लिख देगा:

class Super {
    Number method(Number n) {
        if (this instanceof Sub) {
            return ((Sub) this).method(n);  // *
        } else {
            ... 
        }
    }
}

संकलित करने के लिए चिह्नित रेखा के लिए, ओवरराइडिंग विधि का विधि पैरामीटर ओवरराइड विधि के विधि पैरामीटर का एक सुपरटेप होना चाहिए, और वापसी प्रकार ओवरराइड विधि के उप प्रकार का होना चाहिए। औपचारिक रूप से बोलते हुए, एफ (ए) = पैरामीर्टटाइप (विधि एस्क्लेक्लेरिन (ए)) कम से कम contravariant होना चाहिए, और यदि एफ (ए) = वापसी प्रकार (विधि asdeclaredin (ए)) कम से कम covariant होना चाहिए।

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

class Collection {
    Iterator iterator() { ... }
}

class List extends Collection {
    @Override 
    ListIterator iterator() { ... }
}

मुझे उम्मीद है कि मैंने सबकुछ ढंका - या बल्कि, सतह खरोंच। फिर भी मुझे उम्मीद है कि यह अमूर्त, लेकिन प्रकार भिन्नता की महत्वपूर्ण अवधारणा को समझने में मदद करेगा।


Answer #2

जावा प्रकार प्रणाली लेना, और फिर कक्षाएं:

किसी प्रकार के टी के किसी ऑब्जेक्ट को टी के उप प्रकार के ऑब्जेक्ट के साथ प्रतिस्थापित किया जा सकता है।

टाइप वैरिएंस - क्लास पद्धतियों में निम्नलिखित शिकायतें हैं

class A {
    public S f(U u) { ... }
}

class B extends A {
    @Override
    public T f(V v) { ... }
}

B b = new B();
t = b.f(v);
A a = ...; // Might have type B
s = a.f(u); // and then do V v = u;

यह देखा जा सकता है:

  • टी उप प्रकार एस होना चाहिए ( covariant, बी बी ए के उप प्रकार है )।
  • वी यू ( contravariant , अनुबंध विरासत दिशा के रूप में) के supertype होना चाहिए।

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

कॉन्वर्सिस (जावा में उपलब्ध) उपयोगी है, यह कहने के लिए कि उपप्रकार में एक और अधिक विशिष्ट परिणाम देता है; विशेष रूप से देखा जाता है जब ए = टी और बी = एस। Contravariance का कहना है कि आप एक और सामान्य तर्क को संभालने के लिए तैयार हैं।





java