2011-09-24 17 views
8

मैं इस एक अच्छा सवाल पता नहीं पूछने के लिए है और मैं इसे पूछने के लिए शापित हो सकती है, लेकिन मैं इस सवालइस सामान्य वर्ग घोषणा का क्या अर्थ हो सकता है?

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

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

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

} 
+2

क्या वे दोनों 'सरल' या 'नमूना' हैं, या क्या वे अलग-अलग कक्षाएं हैं? –

+0

इसके बारे में क्षमा करें, इसके SimpleGenericClass - मैंने इसे अपडेट किया है .. धन्यवाद – anonymous

उत्तर

4

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

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

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

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

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

अद्यतनThis SO question on self-bounded generics आपके लिए सहायक हो सकता है।

अद्यतन 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 के लिए एक वैध वापसी प्रकार है! क्या यह अभ्यास में मायने रखता है? कोई विचार नहीं, लेकिन यह बहुत अच्छा है। :)

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

0

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

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

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

new SimpleGenericClass<SampleGenericClass<String>>(); 

आईई। आप स्ट्रिंग के साथ नमूना जेनेरिक क्लास और नमूना जेनरिक क्लास के साथ SimpleGenericClass को parametrize।

+0

क्षमा करें हेन्ड्रिक, यह एक नमूना जेनेरिक क्लास नहीं था बल्कि इसके एकमात्र सरल जेनरिक क्लास ... मैंने सवाल अपडेट किया है .. क्या आप फिर से देख सकते हैं – anonymous

0

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

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

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

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

0

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

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

हो सकता है मुझे लगता है कि आप इस रूप में प्रश्न (? के बजाय 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>> 

अधिक जानकारी के लिए देखें here