2016-02-18 10 views
9

के वर्ग प्रकार बाध्य कैसे मैं इस वर्ग की है। मैं जो चाहता हूं वह this का एक ही वर्ग होना चाहिए। दूसरे शब्दों में जब मैं कक्षा Addressable का विस्तार, ठोस वर्ग MyAddressable साथ में, मैं चाहता हूँ कि विधि hardEquals() हस्ताक्षर हैं:उपवर्ग

void hardEquals(MyAddressable t); 

पूर्णता के लिए:

public class MyAddressable extends Addressable { 

    void hardEquals(MyAddressable t); 

} 
  1. इसे प्राप्त करना संभव है मैं क्या चाहता हूँ?
  2. यदि उत्तर नहीं है, तो क्या यह मेरी कक्षा की बाधा इतनी बेवकूफ है?
+0

यह ठीक से नहीं किया जा सकता है, क्योंकि इसका मतलब है कि 'माई एड्रेस्रेबल' अचानक एक विधि प्राप्त करता है जो दूसरे प्रकार के बजाय 'पता योग्य' स्वीकार करता है, जिसे कक्षा को संभालने के लिए तैयार नहीं किया गया है, यह '' 'प्रकार, यदि अस्तित्व में है, तो केवल संदर्भ में उपयोग किया जा सकता है जैसे? यह 'विस्तारित करता है,' getClass() 'के हस्ताक्षर की तरह यह दिखाता है। – Ferrybig

उत्तर

2

सामान्य रूप से यह संभव नहीं है। आपके परिदृश्य के बारे में थोड़ी देर सोचने पर समस्या स्पष्ट हो जाती है। आपके पास उस वर्ग Addressable और इसकी विधि hardEquals है जो मांग करती है कि इसके पैरामीटर के बराबर प्रकार है। फिर आपके पास सबक्लास

public class MyAddressable extends Addressable { 
    void hardEquals(MyAddressable t); 
} 

है जो इरादे से काम करता है। अब उपवर्ग के उपवर्ग कल्पना:

public class GrandChild extends MyAddressable { 
    void hardEquals(MyAddressable t); 
} 

यहाँ, आप एक वर्ग जो को स्वीकार करना चाहिए MyAddressablehardEquals के रूप में 'पैरामीटर के रूप में यह पैरामीटर प्रकार सीमित करने, यानी चीजों को स्वीकार नहीं द्वारा एक विधि को ओवरराइड करने के लिए अनुमति नहीं है है कि superclass स्वीकार कर लिया। आखिरकार, आप हमेशा MyAddressable प्रकार का चर कर सकते हैं जो वास्तव में GrandChild के उदाहरण को संदर्भित करता है। ऑब्जेक्ट के वास्तविक रनटाइम प्रकार से मेल खाने के लिए पैरामीटर को hardEquals पर प्रतिबंधित करना असंभव होगा।

तो वांछित "पैरामीटर प्रकार this प्रकार से मेल खाना चाहिए" सबक्लास विधियों के साथ नियम विवादों को सुपरक्लास "नियम" के सभी मानकों को स्वीकार करना होगा।


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

class Base { 
    Base/*actually this type*/ clone() { … } 
} 
class SubClass extends Base { 
    SubClass/*actually this type*/ clone() { … } 
} 
class GrandChild extends SubClass { 
    GrandChild/*actually this type*/ clone() { … } 
} 

काम करता है, लेकिन वहाँ गारंटी निर्दिष्ट करने के लिए कोई औपचारिक तरीका है कि this प्रकार लौटाया गया है, इसलिए यह प्रत्येक सबक्लास में सही ओवरराइड जोड़ने के लिए प्रोग्रामर के अनुशासन पर निर्भर करता है।

लेकिन, जैसा कि कहा गया है, पैरामीटर प्रकारों के लिए यह सामान्य रूप से काम नहीं करता है क्योंकि आप सबक्लास में पैरामीटर के प्रकार को संकीर्ण नहीं कर सकते हैं।

1

आप Comparable से एक चाल उधार ले सकता है, और वर्ग घोषणा अपने आप में सामान्य प्रकार निर्दिष्ट:

public abstract class Addressable<T> { 
    abstract <T> void hardEquals(T t); 
} 

यह थोड़ा भद्दा वर्ग परिभाषाओं में परिणाम है, लेकिन यह आपकी आवश्यकता को पूरा करना चाहिए

public class HomeAddress extends Addressable<HomeAddress> { 
    void hardEquals(HomeAddress t) { 
     // implementation 
    } 
} 
1

मुझे आपकी समस्या के लिए एक साफ समाधान के बारे में पता नहीं है।

आप कुछ इस तरह के बारे में सोच सकता है:

public abstract class Addressable<T extends Addressable<T>> { 

    abstract void hardEquals(T other); 

} 

public class MyAddressable extends Addressable<MyAddressable> { 

    @Override 
    void hardEquals(MyAddressable other) { 
    // ... 
    } 

} 

लेकिन यह कुछ मामलों में विफल हो सकता है, जैसे:

public class FakeAddressable extends Addressable<MyAddressable> { 

    @Override 
    void hardEquals(MyAddressable aT) { 
    // ... 
    } 

} 
1

आप एक hardEquals कि केवल इस्तेमाल किया जा सकता के लिए देख रहे हैं बिल्कुल उसी प्रकार के ऑब्जेक्ट्स के साथ इस तरह कुछ काम करना चाहिए:

public abstract class Addressable<T extends Addressable<T>> { 

    abstract boolean hardEquals(T t); 

} 

class X extends Addressable<X> { 

    @Override 
    boolean hardEquals(X t) { 
     return true; 
    } 

} 

class Y extends Addressable<Y> { 

    @Override 
    boolean hardEquals(Y t) { 
     return true; 
    } 

} 

public void test() { 
    X x = new X(); 
    if (x.hardEquals(x)) { 
     System.out.println("Ok"); 
    } 
    Y y = new Y(); 
    // Fails! 
    if (x.hardEquals(y)) { 
     System.out.println("Not OK"); 
    } 
} 

जैसा कि @ होल्गर सही मायने में बताता है - यह उप-वर्गों को विस्तारित करने में सहायता नहीं करता है।

+1

लेकिन अब 'वाई' के उप-वर्गों के बारे में सोचें ... – Holger

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