2010-03-09 18 views
5

मैं Google वेब टूलकिट के साथ काम कर रहा हूं, और मुझे सामान्य इंटरफ़ेस को लागू करने में समस्याएं आ रही हैं। मैं जेनेरिक से वास्तव में परिचित नहीं हूं, यहां किसी और के कोड पर अपग्रेड कर रहा हूं।एक वर्ग के उप-वर्ग जो एक सामान्य इंटरफ़ेस लागू करता है

यहां मैं क्या करना चाहता हूं: मैं एक सामान्य कॉलबैक इंटरफ़ेस का कार्यान्वयन करना चाहता हूं जो कुछ लॉगिंग करता है, और फिर विशिष्ट कॉलबैक परिदृश्यों को संभालने के लिए उस कार्यान्वयन को उपclass करना चाहता है।

public interface AsyncCallback<T> { 
    void MethodFromAsyncCallback(T result); 
} 

सार और ठोस कार्यान्वयन कुछ इस तरह दिखाई:

class CallbackBase implements AsyncCallback<Object> { 
    public abstract void doStuff(Object result); 

    public void MethodFromAsyncCallback(Object result) { 
     // IMPORTANT STUFF 
     // here are things I would like to do for all callbacks, hence the superclass. 

     // Then we do the subclass specific things. 
     doStuff(result); 
    } 
} 

class SpecificCallback extends CallbackBase 
{ 
    public void doStuff(Object result) { 
     Integer i = (Integer)result; 
     // do stuff with i 
    } 
} 

कॉलबैक

public interface MyServiceAsync { 
    public void DoSomeThing(AsyncCallback<Integer>); 
} 

से निकाल दिया जाना आवश्यक हैं

इंटरफेस कुछ इस तरह है और फिर यह सब एक कॉल में एक साथ आता है जो इस तरह दिखता है:

MyServiceAsync myService = (MyServiceAsync)GWT.create(MyServiceAsync.class); 
myService.DoSomeThing(new SpecificCallback()); 

और यहां हमें एक समस्या है!

GWT.create() इंटरफ़ेस मैं बनाया लागू करता है, यह मांग है कि प्रकार AsyncCallback को दी निर्दिष्ट किया जाता है (कहीं और एक प्रकार से मेल खाता है, इस सवाल के दायरे से बाहर), इसलिए DoSomething(AsyncCallback<Integer>) एक वस्तु एक पूर्णांक के बजाय बना रही है। यह मेरे नियंत्रण से बाहर है।

यह शिकायत करता है कि DoSomething()AsyncCallback<Integer> लेता है। मैं इसे कुछ ऐसा दे रहा हूं जो AsyncCallback<Object> है। मुझे जेनेरिक के साथ लगता है, विरासत की अवधारणा कुछ हद तक टूट जाती है?

या तो कैसे मैं इस एक साथ गूदा कर सकते हैं ताकि DoSomething() पहचान लेगा कि SpecificCallback को पूरा करती है कि यह जानना होगा कि

या मैं कैसे संबंध संरचना कर सकते हैं,:

तो मेरे सवाल यह है CallbackBase और SpecificCallback के बीच ताकि डुप्लिकेट कोड से बचा जा सके, लेकिन SpecificCallbackAsyncCallback<Integer> लागू करता है?

धन्यवाद।

class SpecificCallback extends CallbackBase<Integer> { 
    public void doStuff(Integer result) { 
    // no need to cast 
    // do stuff with result 
    } 
} 

फिर अपने DoSomething विधि है, जो एक स्वीकार करता है:

abstract class CallbackBase<T> implements AsyncCallback<T> { 
    public abstract void doStuff(T result); 

    public void MethodFromAsyncCallback(T result) { 
    // general stuff (T is a subclass of Object) 
    doStuff(result); 
    } 
} 

तो फिर तुम अपने विशिष्ट कॉलबैक इस तरह रहना चाहता हूँ:

उत्तर

9

मैं क्या लगता है कि तुम क्या करने की जरूरत CallbackBase इस तरह परिभाषित है AsyncCallback<Integer>, SpecificCallback स्वीकार करेगा।

(पंडिताऊ sidenote: जावा में छोटे अक्षरों के साथ सभी तरीकों शुरू करें)

संपादित

क्या इसके लायक है के लिए, मैं विरासत के बजाय रचना का उपयोग करने के अपने डिजाइन बदलने का सुझाव चाहते हैं। इस मामले में, बल्कि एक अमूर्त वर्ग CallbackBase उपयोग करने और इसे प्रदान की तुलना, आप AsyncCallback<T> का एक ठोस कार्यान्वयन कुछ इस तरह लग सकता है कि का उपयोग करेंगे:

class GeneralCallbackWrapper<T> implements AsyncCallback<T> { 
    private final AsyncCallback<? super T> delegate; 

    public GeneralCallbackWrapper(AsyncCallback<? super T> delegate) { 
    this.delegate = delegate; 
    } 

    public void MethodFromAsyncCallback(T result) { 
    // general stuff here 
    delegate.MethodFromAsyncCallback(result); 
    } 
} 
+0

सौंदर्य, धन्यवाद! – Ipsquiggle

+0

पुन: संपादित करें। हाँ, यह बहुत समझ में आता है। मैं इसे पहले कुछ ऐसा करने के लिए बदलना चाहता था, लेकिन लगा कि मैं एक समय में अपने भ्रम को एक कदम बता दूंगा। ;) – Ipsquiggle

+0

क्या इनमें से किसी एक को संभवतः दो संभावित प्रकारों के लिए विस्तारित करना संभव है? जैसे वैचारिक रूप से 'AsyncCallback लागू करता है, AsyncCallback ' लागू करता है? – Ipsquiggle

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