2013-08-22 13 views
8

लौटा रहा है मुझे this question में वर्णित समस्या का सामना करना पड़ रहा है, लेकिन सभी जानवरों और @SuppressWarning टिप्पणियों के बिना समाधान (यदि संभव हो) ढूंढना चाहते हैं।विरासत विधि संदर्भ प्रकार

एक बेहतर समाधान एक ही है कि द्वारा संदर्भित एक पर बनाता होगा:

  • को हटाने डाले
  • @SuppressWarning को हटाने
के आधार पर

यहां प्रस्तुत 2 अंकों के साथ वर्गीकृत किया जाएगा समाधान मानदंड। यदि अंक 2 से अधिक अंक हैं तो बाउंटी अधिकांश बिंदुओं या "सबसे सुरुचिपूर्ण" के साथ समाधान में जाता है।

+0

के लिए इतना तंत्र की वजह से 2 दिनों में इनाम जोड़ने करेंगे उपहार देने की पेशकश। हालांकि, अभी अपना जवाब पोस्ट करने के लिए स्वतंत्र महसूस करें। – pnt

+0

संबंधित: [क्या वर्तमान प्रकार को एक प्रकार चर के साथ संदर्भित करने का कोई तरीका है?] (Http://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current -टाइप-ए-टाइप-वेरिएबल) –

उत्तर

9

कोई कास्ट, कोई @SuppressWarning, कुछ पंक्तियां केवल:

public abstract class SuperClass<T extends SuperClass<T>> { 
    protected T that; 
    public T chain() { 
     return that; 
    } 
} 

public class SubClass1 extends SuperClass<SubClass1> { 
    public SubClass1() { 
     that = this; 
    } 
} 

public class SubClass2 extends SuperClass<SubClass2> { 
    public SubClass2() { 
     that = this; 
    } 
} 
+1

इसे सबसे अच्छा जवाब के रूप में चुना गया था क्योंकि यह पूरी तरह से कास्ट करता है, मेरे पास कोई @SuppresWarnings नहीं है और मेरे अनुसार, सबसे सुंदर है क्योंकि यह विधि ओवरराइडिंग से भी बचाता है (संदर्भ जिसे आपको "ओवरराइड" करना क्लीनर दिखता है और कम कोड की आवश्यकता है; यह उपयोगकर्ता से भी छिपा हुआ है कि आप कुछ भी ओवरराइड करते हैं)। 23 घंटे में बक्षीस का पुरस्कार होगा। – pnt

+0

@pnt यह मूल रूप से आपके संदर्भित प्रश्न में स्वीकृत उत्तर के समान समाधान है। आप इसे वहां क्यों पसंद नहीं करते और इसे स्वीकार करते हैं? –

+1

@ फ्रैंकोइस बुर्जियो वास्तव में, यह वही समाधान नहीं है। दूसरे समाधान में, 'रिटर्न (टी) के साथ;' अमूर्त वर्ग में, अनुपालन समय पर संकलित समय पर नहीं जान सकता है अगर कास्ट सुरक्षित है (भले ही यह हो, केवल डेवलपर जानता हो), इस प्रकार इसकी आवश्यकता @Suppress चेतावनी एनोटेशन। मेरे समाधान में, 'उस' को सीधे उप-वर्ग के भीतर सेट करने के बाद से कास्ट करने की आवश्यकता नहीं है। और यह * नो-कास्ट समाधान * सटीक रूप से यहां पूछा गया था। – sp00m

1

एक समाधान बाल वर्ग में विधि को ओवरराइड करना और वापसी प्रकार को एक और विशिष्ट, यानी बदलना है। बच्चे का प्रकार इसके लिए कास्टिंग की आवश्यकता है। इसके बजाय ठेठ (Child) कलाकारों का उपयोग करने का, Class#cast(Object) विधि

public class Parent { 
    public Parent example() { 
     System.out.println(this.getClass().getCanonicalName()); 
     return this; 
    } 
} 

public class Child extends Parent { 
    public Child example() { 
     return Child.class.cast(super.example()); 
    } 

    public Child method() { 
     return this; 
    } 
} 

डाली मानक विधि भीतर छिपा हुआ है का उपयोग करें। Class के स्रोत से।

public T cast(Object obj) { 
    if (obj != null && !isInstance(obj)) 
     throw new ClassCastException(cannotCastMsg(obj)); 
    return (T) obj; 
} 
+0

वास्तव में कोई समाधान नहीं है क्योंकि यह कास्ट को नहीं हटाता है (केवल लपेटता है और उन्हें छुपाता है) और संदर्भित प्रश्न में मूल समस्या को हल नहीं करता है। हां, ज़ाहिर है कि आप एक और विशिष्ट प्रकार को वापस करने के लिए विधि को ओवरराइड कर सकते हैं लेकिन पूरा बिंदु इसका पुन: उपयोग करना है और इसे प्रत्येक बच्चे में ओवरराइड करना नहीं है। – pnt

+0

@pnt समस्या बताई गई थी _ मैं अतिरिक्त इंटरफेस और अतिरिक्त विधियों का उपयोग किए बिना इसे कार्यान्वित करना चाहता हूं, और क्लास कास्ट, सहायक तर्क आदि के बिना इसका उपयोग करना चाहता हूं ._ बात यह है कि आप नहीं कर सकते हैं। प्रस्तावित समाधानों में सभी के पास अतिरिक्त विधियां और/या अतिरिक्त तर्क हैं। या तो आप प्रश्न में विधि को ओवरराइड करते हैं या आप माता-पिता में एक और विधि पेश करते हैं और उस पर ओवरराइड करते हैं। जेनेरिक समाधान में, आपको एक प्रकार पैरामीटर भी पेश करने की आवश्यकता है। –

5

एक दृष्टिकोण Parent कक्षा में एक सार विधि getThis() को परिभाषित है, और सभी Child कक्षाएं इसे ओवरराइड, this संदर्भ लौटने बनाना है। यह कक्षा पदानुक्रम में this ऑब्जेक्ट के प्रकार को पुनर्प्राप्त करने का एक तरीका है।

कोड इस तरह दिखेगा:

abstract class Parent<T extends Parent<T>> { 

    protected abstract T getThis(); 

    public T example() { 
     System.out.println(this.getClass().getCanonicalName()); 
     return getThis();   
    } 
} 

class ChildA extends Parent<ChildA> { 

    @Override 
    protected ChildA getThis() { 
     return this; 
    } 

    public ChildA childAMethod() { 
     System.out.println(this.getClass().getCanonicalName()); 
     return this; 
    } 
} 

class ChildB extends Parent<ChildB> { 

    @Override 
    protected ChildB getThis() { 
     return this; 
    } 

    public ChildB childBMethod() { 
     return this; 
    } 
} 


public class Main { 

    public static void main(String[] args) throws NoSuchMethodException { 
     ChildA childA = new ChildA(); 
     ChildB childB = new ChildB(); 

     childA.example().childAMethod().example(); 
     childB.example().childBMethod().example(); 
    } 
} 

आवश्यकता के अनुसार के रूप में, कोई कास्टिंग और कोई @SuppressWarnings। मैंने Angelika Langer - Java Generics FAQs से कुछ दिन पहले इस चाल को सीखा।

संदर्भ:

+1

आप घोषणा करना चाहते हैं 'माता-पिता <टी अभिभावक > 'बढ़ाता है। अन्यथा आप 'माता-पिता ' बढ़ा सकते हैं और विधि श्रृंखला समाप्त हो जाएगी 'स्ट्रिंग getThis() '। –

+0

@ सॉटिरियोसेलिमैनोलिस। आह! सही। धन्यवाद :) –

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