2011-08-31 9 views
10

आज मैं कुछ दिलचस्प पर ठोकर खाई ओवरराइड करना। निम्नलिखित जावा 6 वर्ग मान लें: यदि आप ऊपर के उदाहरण संकलित करने के लिए प्रयास करते हैं तोएक विधि का उपयोग प्रकार विलोपन

public class Ereasure { 

    public Object get(Object o) { 
     return null; // dummy 
    } 

    public static class Derived<T> extends Ereasure{ 
     // (1) 
     @Override 
     public Object get(T o) { 
       return super.get(o); 
     } 
     // (2) 
     /* 
     @Override 
     public Object get(Object o) { 
       return super.get(o); 
     }*/ 

    } 
} 

, संकलक का कहना है Ereasure.java:9: विधि पर हावी नहीं होता या एक महाप्रकार से एक विधि को लागू @Override हैं (! जो आवश्यक नहीं होना चाहिए) आप @Override टिप्पणी निकालने, यह कहता है Ereasure.java:8: नाम टकराव: Ereasure में Ereasure.Derived में (टी) हो जाते हैं और मिल (java.lang.Object) है एक ही विलोपन , अभी तक न तो अन्य इसमें कुछ समय contradictional है ओवरराइड करता है, के बाद से टी वस्तु को erease चाहिए और ओवरराइड वजह माता पिता कक्षाएं विधि मिलता है।

आप छोड़ देते हैं (1) unannotated और टिप्पणी हटाएं (2) तो (1) भार के (2) यह या तो काम नहीं होगा। संकलक उत्पादन:

Ereasure.java:15: get(T) is already defined in Ereasure.Derived 
    public Object get(Object o) { 

एक निष्कर्ष के रूप में, टी वस्तु को ereased की जा रही है, लेकिन ओवरराइड नहीं कर सकते माता पिता विधि मिलता है।

मेरा प्रश्न है, क्यों उदाहरण के कम से कम एक संकलन dooesn't?

+0

@ toto2 मैं अपने दाहिने लगता है, लेकिन मैं भी अपने एक दिलचस्प प्रतीत होता है गैर-दस्तावेजी कोने मामले में सोचते हैं। टाइप एरर पर सूर्य कंपाइलर नोट्स के मुताबिक डेरिवेट में विधि परिभाषा को व्युत्पन्न प्रकार में व्युत्पन्न प्रकार को सार्वजनिक ऑब्जेक्ट प्राप्त करने (ऑब्जेक्ट ओ) में परिवर्तित करना चाहिए, क्योंकि इसके बाद माता-पिता का सबसिग्नेचर इसे ओवरराइड करना चाहिए। मुझे लगता है कि वह सही है कोई रास्ता नहीं है कि वहाँ जब विधि प्रेषण अस्पष्टता कि असीम प्रकार से परिणाम को हल करने बाईटकोड में इस बात मंथन। – nsfyn55

उत्तर

2

एक साधारण अनुमान जब भार के जो निश्चित रूप से कोई मतलब नहीं होगा की गणना संकलक सामान्य दृश्य का उपयोग नहीं करता है, क्योंकि कभी कभी टी हो सकता है दूसरी बार अपने एक अन्य प्रकार वस्तु। overridding तो एक चलती लक्ष्य टी जो पूरी तरह से गलत है पर निर्भर हो गए हैं, विशेष रूप से एक से अधिक तरीकों सब "मिल" लेकिन विभिन्न एकल पैरामीटर प्रकार के साथ बुलाया थे। ऐसी स्थिति में यह सिर्फ मतलब नहीं होता और एक अनुमान पर वे सिर्फ बातें सरल रखने का फैसला किया।

+0

लेकिन आम तौर पर बोलते हुए, प्रत्येक जेनेरिक एक वस्तु है क्योंकि हर जावा वर्ग ऑब्जेक्ट से प्राप्त होता है ... – user3001

+0

उपरोक्त में, टी की निचली सीमाएं ऑब्जेक्ट है, अन्य घोषणाएं मिहट और अक्सर अलग-अलग निचले सीमाओं का उपयोग करती हैं। –

7

आप कारण है कि यह असंभव है कि आप क्या चाहते करने के लिए नीचे दिए गए उदाहरण में देख सकते हैं:

public class Erasure { 

    public void set(Object o) { 
     return; 
    } 

    // method overloading: (which is valid) 
    public void set(String s) { 
     return; 
    } 

    public static class Derived<S> extends Erasure { 

     // Oops... which one am I supposed to override? 
     // (It would actually be overloading if S was a concrete type 
     // that is neither Object nor String.) 
     @Override 
     public void set(S o) { // does not compile 
     super.set(o); 
     } 
    } 
} 

आपकी समस्या का हल है कि Erasure एक पैरामिट्रीकृत वर्ग होना चाहिए।

1

एक मामले में जहां आप दोनों एक गेटर और एक सेटर जेनरिक के रूप में अधिरोहित है पर विचार करें।

Derived<String> d = new Derived<String(); 
Erasure e = d; 
e.set(new Object()); 
String s = d.get(); //Class cast exception 

जेनरिक के मौलिक प्राचार्य कि एक वर्ग डाली अपवाद केवल अगर वहाँ या तो (क) एक स्पष्ट डाली या (ख) एक चेतावनी हो सकता है है। आप क्या चाहते थे करने की अनुमति दी गई है, तो उक्त में से किसी के बिना एक अपवाद फेंक होगा।

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