2014-06-17 3 views
8

जावा 8 में मैं कुछ इस तरह है:क्या आप इंटरफ़ेस से मूल इंटरफ़ेस की डिफ़ॉल्ट विधि को इंटरफ़ेस से उप-वर्गीकृत कर सकते हैं?

package test; 
public class SimpleFuncInterfaceTest { 
    public static void carryOutWork(AFunctionalInterface sfi){ 
     sfi.doWork(); 
    } 
    public static void main(String[] args) { 
     carryOutWork(() -> System.out.println("Do work in lambda exp impl...")); 
     AImplementor implementsA = new AImplementor(); 
     //carryOutWork(() -> implementsA.doWork()); 
     BImplementor implementsB = new BImplementor(); 
     carryOutWork(() -> implementsB.doWork()); 
    } 
} 

@FunctionalInterface 
interface AFunctionalInterface { 
    public void doWork(); 
    default public void doSomeWork(){ 
     System.out.println("FOO"); 
    } 
} 

@FunctionalInterface 
interface BFunctionalInterface extends AFunctionalInterface { 
    @Override 
    default public void doSomeWork(){ 
     System.out.println("BAR");//Unreachable in same object? 
    } 
} 

class AImplementor implements AFunctionalInterface { 
    @Override 
    public void doWork() { 
     doSomeWork(); 
    } 
} 

class BImplementor extends AImplementor implements BFunctionalInterface { 
    public void doSomeWork(){ 
     super.doSomeWork(); 
     new BFunctionalInterface(){ 
      @Override 
      public void doWork() { 
      }}.doSomeWork(); 
      System.out.println("WUK WUK"); 
    } 
    @Override 
    public void doWork() { 
     doSomeWork(); 
    } 
} 

वहाँ एक रास्ता एक गुमनाम आंतरिक वर्ग बनाने के लिए करने और उन्हें लागू करने के बिना implementsB से डिफ़ॉल्ट कार्यात्मक इंटरफ़ेस व्यवहार कॉल करने के लिए है?

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

उदाहरण के लिए यदि किसी संसाधन को अनलॉक या प्रदान की गई पहुंच डेटाबेस कहती है, और बी दूसरे संसाधन (अन्य डेटाबेस) को अनलॉक करता है, तो मुझे कोड अनलॉक करने का कोई तरीका नहीं दिखता है और फिर बी को कार्यात्मक के उपयोग के माध्यम से इस अनुबंध को लागू करने का कोई तरीका नहीं दिखता है इंटरफ़ेस, जिसमें ए और बी को बुलाया जाना आवश्यक है। एक स्तर गहरा आप इसे कर सकते हैं, लेकिन एन स्तर गहरा दिखता है जैसे यह संभव नहीं है।

मैं महंगी कॉल करने से बचने के लिए लैम्बडा का उपयोग करना चाहता था लेकिन मेरी लाइब्रेरी के उपयोगकर्ताओं पर संचालन के अर्थपूर्ण क्रम को लागू करने का इरादा रखता था।

यह प्रश्न "जावा में एक डिफ़ॉल्ट विधि को स्पष्ट रूप से कॉल करने" जैसा ही है, क्योंकि यह सवाल एन स्तरों को गहराई से इंटरफ़ेस के बारे में है, केवल माता-पिता इंटरफेस डिफ़ॉल्ट विधि को कॉल नहीं करता है।

+0

तो आप 'BIFplementor' से' BFunctionalInterface.doSomeWork' को कॉल करना चाहते हैं? –

+1

"जावा में एक डिफ़ॉल्ट विधि को स्पष्ट रूप से कॉल करने" के समान प्रश्न नहीं है, यह गहराई के एन स्तर के बारे में पूछता है, जबकि वह समाधान केवल एक स्तर के संकेत के लिए अनुमति देता है। – ggb667

उत्तर

16

आप InterfaceName.super का उपयोग कर विरासत में मिली interface default विधि का आह्वान कर सकते हैं। नियम अन्य super विधि आमंत्रणों के समान हैं: आप विरासत में प्राप्त विरासत विधि का आह्वान कर सकते हैं, लेकिन आप सीधे उस विधि को नहीं बुला सकते हैं जिसने विरासत विधि को ओवरराइड किया हो। जैसे

interface A 
{ 
    void foo(); 
    default void toOverride() { 
     System.out.println("A"); 
    } 
} 
interface B extends A 
{ 
    default void toOverride() { 
     A.super.toOverride(); 
     System.out.println("B"); 
    } 
} 
interface C extends B 
{ 
    default void toOverride() { 
     A.super.toOverride();// does not work 
     B.super.toOverride(); 
     System.out.println("B"); 
    } 
} 
class D implements B 
{ 
    public void toOverride() { 

    }  
    public void foo() { 
     D.this.toOverride(); 
     B.super.toOverride(); 
     A.super.toOverride(); // does not work! 
    } 
} 

लेकिन हर अधिभावी विधि अपने सुपर विधि का आह्वान करता है, तो आप आमंत्रण की एक श्रृंखला है। हालांकि, ध्यान रखें कि हम इंटरफेस के बारे में बात कर रहे हैं। एक कार्यान्वयन हमेशा super को आमंत्रित किए बिना डिफ़ॉल्ट विधि को ओवरराइड कर सकता है।

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