2012-12-21 18 views
18

मान लीजिए मैं वर्ग संरचना निम्नलिखित है का ही हिस्सा स्वीकार करते हैं:जेनेरिक विधि है कि कक्षाओं

class Base {} 
class A extends Base {} 
class B extends Base {} 
class C extends Base {} 

मैं विधि, इस बात का एक और बी नहीं बल्कि के उदाहरण सी उदाहरणों को स्वीकार करता है लिखना चाहते हैं।
क्या मैं इसे जावा में प्राप्त कर सकता हूं?

मैं जानता हूँ कि यह अच्छा विरासत स्थिति (एक और बीसी से आम माता-पिता अलग होना चाहिए) नहीं है, लेकिन मैं सिर्फ उत्सुक जावा जिस तरह से इस तरह की स्थिति को संभालने के लिए है हूँ।

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

उत्तर

3

लगता है आपके सवालों के जवाब "है नहीं, जावा एक ऐसी से निपटने का एक मानक तरीका नहीं है मुसीबत"। और यदि आपको यह समस्या है तो आप विरासत को ठीक करने या चतुर तकनीक given by MrSmith42 का उपयोग करने जैसे अन्य उत्तरों को देख सकते हैं।

+0

सही और सरल उत्तर के लिए धन्यवाद :) –

+4

@ MichałHerman सही? 17 - 1 ... blimey, यह काम पर होने की तरह है। – NimChimpsky

+0

@NimChimpsky चिंता न करें, इस तरह की चीज़ों के लिए बैज हैं। :) – MikeTheLiar

2

आप एक वस्तु का एक निश्चित प्रकार है या नहीं, यह जांचने के लिए आप instanceof का उपयोग कर सकते हैं।

बेहतर विचार बेहतर विरासत संरचना होगी।

+0

स्पष्ट होने के लिए: जावा में, 'exampleof' subclasses के लिए काम करता है। यही है, 'सी सी = नया सी(); सी उदाहरण बी बी सच हो जाएगा। यदि आप 'सी' को बाहर करना चाहते हैं, तो आपको इसे स्पष्ट रूप से जांचना होगा। (एक टिप्पणी जोड़ना क्योंकि पहली नज़र में यह जवाब मुझे स्पष्ट नहीं था।) –

43

interface का उपयोग करें और केवल A और B इसे कार्यान्वित करें।

13

क्या आप एक इंटरफेस का उपयोग कर सकते हैं? जैसे

class Base {} 
interface MyGenericInterface {} 
class A extends Base implements MyGenericInterface {} 
class B extends Base implements MyGenericInterface {} 
class C extends Base {} 

इस तरह, विधि MyGenericInterface के कार्यान्वयन स्वीकार कर सकते हैं, और ए और बी के बाद से इंटरफ़ेस को लागू लेकिन सी नहीं, यह बी ए के उदाहरण और लेकिन सी नहीं, के रूप में आवश्यक स्वीकार करेंगे करता है।

8

कुछ स्वीकार करना चाहिए, तो A, B लेकिन नहीं C तो आप क्यों C पहली जगह में Base से इनहेरिट है पर पुनर्विचार करना चाहिए। आप उत्तराधिकार के एक अतिरिक्त परत जोड़ सकते हैं:

---Base--- 
    |  | 
--Sub--  C 
|  | 
A  B 

तो फिर आप अपने विधि केवल प्रकार Sub की वस्तुओं को स्वीकार करने की अनुमति दे सकता। Sub को कुछ भी करने की ज़रूरत नहीं है, और वे सभी तकनीकी रूप से भी हैं, Base

एक तेज समाधान एक गंदा if(arg.instanceof(C)) हालांकि होगा ...

8

आप अपवाद का उपयोग कर कार्यावधि में इसे संभाल कर सकते हैं:

void genericMethod(Base arg_in) 
{ 
    if(arg_in instanceof C) 
    { 
     throw IllegalArgumentException("C class not accepted."); 
    } 

    ... 
    ... 
} 
8

एक प्रकार-पदानुक्रम बदला नहीं जाना चाहिए क्योंकि आप करना चाहते हैं ऐसी एक विधि। लेकिन जिस मामले में आप ऐसी विधि लेना चाहते हैं, यह इंगित कर सकता है कि आपको अपने टाइप-पदानुक्रम पर विचार करना चाहिए।

लेकिन आप अपने प्रकार अच्छी तरह से तैयार कर रहे हैं यकीन है कि, क्या इस दृष्टिकोण के बारे में कर रहे हैं: मैं

public class T { 

     public void doSomething(final A a) { 
      doSomthing(a); 
     } 

     public void doSomething(final B b) { 
      doSomthing(b); 
     } 

     private void doSomthing(final Base b) { 

      // Here is the implementation 

     } 

    } 
+0

मुझे नहीं पता कि आप वहां 'अंतिम' कीवर्ड के साथ क्या चाहते थे, लेकिन यह कॉल पर होने वाले विस्तृत रूपांतरण को रोक नहीं पाएगा साइट। चूंकि 'सी' का प्रत्येक उदाहरण' बी' का उदाहरण है, इसलिए 'सी' के उदाहरणों को आपके' कुछ() 'विधि में पारित करना हमेशा संभव होगा। –

+0

आपको क्यों लगता है कि "सी बी का एक उदाहरण है"? ए, बी, सी सभी केवल बेस – MrSmith42

+0

'फाइनल' का विस्तार करते हैं, कार्यक्षमता के साथ कुछ भी नहीं है। बस एक कोडिंग सम्मेलन का उपयोग किया जाता है। – MrSmith42

2

जेनिक्स टाइप सुरक्षा के लिए है। अवधि। मनमानी चीजों को "अनुमति" या "अस्वीकार" नहीं करना है। ए और बी को अनुमति देने के लिए कोई प्रकार-सुरक्षा कारण नहीं है और सी

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