मुझे पता है कि यह पूछने के लिए एक अच्छा सवाल नहीं है और मुझे इसे पूछने के लिए शापित हो सकता है लेकिन मुझे इस सवाल पर मदद पाने के लिए कोई जगह नहीं मिल रही है

नीचे एक सामान्य वर्ग है जो मेरे साक्षात्कार प्रश्न में दिखाई दिया (जिसे मैं पहले ही विफल कर चुका हूं)। प्रश्न यह बताना था कि यह वर्ग घोषणा क्या कर रही है और किन परिस्थितियों में इसका उपयोग किया जा सकता है?

मुझे जेनेरिक प्रोग्रामिंग की बहुत सीमित समझ है लेकिन मैं समझता हूं कि 'टी' टाइप है और 'विस्तारित' का मतलब है कि टाइप को 'सिंपलजेनेरिक क्लास' विरासत में मिला होना चाहिए लेकिन मुझे '?' समझ में नहीं आता है। अंत में और किन परिस्थितियों में इस वर्ग का संभावित रूप से उपयोग किया जा सकता है

public abstract class SimpleGenericClass<T extends SimpleGenericClass<?>> {

}
8
anonymous 24 सितंबर 2011, 11:17

5 जवाब

सबसे बढ़िया उत्तर

पहला, क्योंकि SimpleGenericClass वर्ग सार है, इसका मतलब उपवर्ग होना है।

दूसरा, यह एक जेनेरिक वर्ग है जिसका अर्थ है कि कक्षा के अंदर कहीं न कहीं आप लगभग निश्चित रूप से सामान्य पैरामीटर T को एक फ़ील्ड के प्रकार के रूप में उपयोग कर रहे होंगे।

public abstract class SimpleGenericClass<T...> {
    T x;
}

अब यहां पहली दिलचस्प बात यह है कि T बाध्य है। क्योंकि इसे T extends SimpleGenericClass<?> के रूप में घोषित किया गया है, यह केवल SimpleGenericClass<?> या SimpleGenericClass<?> का कुछ उपवर्ग हो सकता है। आपने ? के बारे में भी पूछा। इसे वाइल्डकार्ड के रूप में जाना जाता है और इसकी बहुत अच्छी व्याख्या पर दी गई है। वाइल्डकार्ड पर जावा ट्यूटोरियल। आपके मामले में हम कहेंगे कि यह "अज्ञात का SimpleGenericClass" है। जावा में इसकी आवश्यकता है क्योंकि SimpleGenericClass<Object> SimpleGenericClass<String> का सुपरक्लास नहीं है, उदाहरण के लिए।

हालांकि दूसरी दिलचस्प बात यह है कि चूंकि T किसी प्रकार का SimpleGenericClass है, इसलिए आपकी कक्षा पुनरावर्ती संरचनाओं को परिभाषित करने की संभावना से कहीं अधिक है। मेरे दिमाग में क्या आता है पेड़ (अभिव्यक्ति पेड़ों के बारे में सोचें) जहां SimpleGenericClass (सार) नोड प्रकार है, जिसे सभी प्रकार के विशेष नोड प्रकारों के साथ उप-वर्गीकृत करने के लिए डिज़ाइन किया गया है।

अद्यतन करें सेल्फ-बाउंडेड जेनरिक पर यह SO प्रश्न हो सकता है आपके लिए मददगार।

अपडेट 2

मैं आगे बढ़ गया और कुछ कोड एक साथ रखा जो दिखाता है कि इसका उपयोग कैसे किया जा सकता है। ऐप कुछ भी नहीं करता है लेकिन यह संकलित करता है और यह आपको दिखाता है कि सामान्य सीमाएं कुछ संभावित-सार्थक बाधाओं की आपूर्ति कैसे कर सकती हैं।

public abstract class Node<T extends Node<?>> {
    public abstract T[] getChildren();
}

class NumberNode extends Node {
    int data;
    public Node[] getChildren() {return new Node[]{};}
}

class IdentifierNode extends Node {
    int data;
    public Node[] getChildren() {return new Node[]{};}
}

class PlusNode extends Node {
    NumberNode left;
    NumberNode right;
    public NumberNode[] getChildren() {return new NumberNode[]{};}
}

यहाँ अच्छी बात यह है कि NumberNode[], PlusNode.getChildren के लिए एक मान्य रिटर्न प्रकार है! क्या यह व्यवहार में मायने रखता है? कोई विचार नहीं, लेकिन यह बहुत अच्छा है। :)

यह सबसे बड़ा उदाहरण नहीं है, लेकिन सवाल खुला अंत था ("ऐसी चीज़ का क्या उपयोग किया जा सकता है?")। पेड़ों को परिभाषित करने के अन्य तरीके भी हैं।

4
Community 23 मई 2017, 15:19

इसका वास्तव में केवल यह मतलब है कि आप क्लास के उपयोगकर्ता को SimpleGenericClass को टाइप T के साथ क्लास के इंस्टेंस को पैरामीट्रिज करने की अनुमति देते हैं। हालाँकि, T किसी भी प्रकार का नहीं हो सकता है, लेकिन यह SampleGenericClass (या स्वयं sampleGenericClass) का एक उप-प्रकार होना चाहिए।

SimpleGenericClass वर्ग के शेष कोड में आप विधि हस्ताक्षर में टाइप T का उपयोग कर सकते हैं।

आइए एक सेकंड के लिए मान लें कि SimpleGenericClass सार नहीं है। इसका उपयोग करते समय, आप तब लिख सकते हैं:

new SimpleGenericClass<SampleGenericClass<String>>();

अर्थात। आप SimpleGenericClass को sampleGenericClass के साथ और sampleGenericClass को स्ट्रिंग के साथ parametrize करते हैं।

0
Hendrik 24 सितंबर 2011, 11:26

यह मूल रूप से कहा गया है: इस वर्ग में आपके पास टी नामक एक प्रकार प्लेसहोल्डर है, और उस प्लेसहोल्डर पर प्रतिबंध है, यह SimpleGenericClass या इसे विस्तारित करने वाला कुछ प्रकार का होना चाहिए। एक बार जब आप उस नियम का पालन करते हैं तो आप अपनी कक्षा के उदाहरण बना सकते हैं और टी को वास्तविक प्रकार दे सकते हैं, जिसे बाद में उस वर्ग के तरीकों में इस्तेमाल किया जा सकता है, कुछ इस तरह:

public class C <T extends Number>{

    public void doSomething(T t) {

    }

    public static void main(String... args) {
        //works:
        C<Number> c = new C<Number>();
        c.doSomething(new Number() {
            //Aonimous implementation of number

        });

        //won't work
        //C<Object> c = new C<Object>();

        C<Integer> c2 = new C<Integer>();       
        c2.doSomething(new Integer(1));
        //won't work
        //c2.doSomething(new Number() {

            //Aonimous implementation of number
        //});
    }
}

इस समय SimpleGenericClass<?> काफी बेमानी है। यदि इस वर्ग पर किसी अन्य सामान्य प्रकार की आवश्यकता है, तो आपके पास एक से अधिक (SimpleGenericClass<T extends SimpleGenericClass, T2 extends Whatever>) हो सकते हैं

0
Shivan Dragon 24 सितंबर 2011, 11:44

परिभाषा के अनुसार यह कहता है कि SimpleGenericClass एक प्रकार <T> पर काम कर सकता है जो SimpleGenericClass का उपवर्ग है।

इसलिए मुझे लगता है कि कुछ ऑपरेशन होंगे जो <T> पर काम करेंगे।

अब यह देखने के लिए कि कोई इस तरह के टेम्पलेट को क्यों परिभाषित करेगा - (मैं वास्तव में इतना नहीं सोच सकता) एक ऐसा परिदृश्य हो सकता है जहां SimpleGenericClass एक अमूर्त वर्ग है (बस एहसास हुआ कि यह ओपी के अनुसार है: पी ) और उम्मीद करता है कि यह किसी भी ठोस वर्ग पर काम कर सकता है?

दोस्तों आपको क्या लगता है?

0
Nrj 24 सितंबर 2011, 11:49

मुझे लगता है कि आपको प्रश्न इस रूप में मिल गया है (? के बजाय T):

public abstract class SimpleGenericClass<T extends SimpleGenericClass<T>>

इस कोड पर एक नज़र डालें:

abstract class Foo<SubClassOfFoo extends Foo<SubClassOfFoo>>
{
    /** subclasses are forced to return themselves from this method */
    public abstract SubClassOfFoo subclassAwareDeepCopy();
}

class Bar extends Foo<Bar> {
    public Bar subclassAwareDeepCopy() {
        Bar b = new Bar();
        // ...
        return b;
    }
}

Bar b = new Bar();
Foo<Bar> f = b;
Bar b2 = b.subclassAwareDeepCopy();
Bar b3 = f.subclassAwareDeepCopy(); // no need to cast, return type is Bar

Foo<SubClassOfFoo extends Foo<SubClassOfFoo>> के साथ चल रही चाल है:

  • Foo के किसी भी उपवर्ग को Foo को एक प्रकार का तर्क देना चाहिए।
  • उस प्रकार का तर्क वास्तव में Foo का उपवर्ग होना चाहिए।
  • Foo (जैसे Bar) के उपवर्ग उस मुहावरे का अनुसरण करते हैं जो टाइप वह तर्क जो वे Foo को देते हैं, वह स्वयं है।

  • फू की एक विधि है जो SubClassOfFoo लौटाती है। संयुक्त उपरोक्त मुहावरे के साथ, यह फू को एक अनुबंध तैयार करने की अनुमति देता है कि कहते हैं "मेरे किसी भी उपवर्ग को subclassAwareDeepCopy() और . को लागू करना होगा उन्हें यह घोषित करना होगा कि यह उस वास्तविक उपवर्ग को लौटाता है"।

यह कहने के लिए कि एक और तरीका: यह मुहावरा एक सुपरक्लास (जैसे एब्सट्रैक्ट फैक्ट्री) को उन तरीकों को परिभाषित करने की अनुमति देता है जिनके तर्क प्रकार और रिटर्न प्रकार उपवर्ग प्रकार के संदर्भ में हैं, न कि सुपरक्लास प्रकार के।

उदाहरण के लिए यह चाल Enum JDK वर्ग में की जाती है:

public abstract class Enum<E extends Enum<E>>

अधिक विवरण के लिए यहां देखें।

0
Andrey 24 सितंबर 2011, 11:59