2012-05-27 13 views
5

मेरे पास एक सैद्धांतिक प्रश्न है कि एक भाषा में निम्नलिखित परिदृश्य से निपटने के लिए कैसे करें जो एकाधिक विरासत की अनुमति नहीं देता है।एकाधिक विरासत के बिना एकाधिक विरासत और कोड डुप्लिकेशन के बिना

कल्पना कीजिए कि मैं एक आधार वर्ग फू है और इसे से मैं तीन उप-वर्गों बनाने के लिए बधाई देने के लिए कर रहा हूँ:

  • कक्षा बार विरासत फू और कार्यक्षमता को लागू करता है 'ए'
  • क्लास बाज़ विरासत फू और कार्यान्वयन कार्यक्षमता "बी"
  • कक्षा Quxफू विरासत और लागू करता है कार्यक्षमताओं "ए" और "बी"

कल्पना कीजिए कि कोड कार्यक्षमताओं 'ए' और 'बी' को लागू करने के हमेशा एक ही है। क्या केवल एक बार "ए" और "बी" के लिए कोड लिखने का कोई तरीका है, और फिर उचित कक्षाएं लागू होती हैं (या "उत्तराधिकारी")?

+0

कोई विशेष भाषा? जावा? सी#? कुछ और? – Tudor

+0

आप अपने खाद्य वर्ग के भीतर समान कार्यक्षमता को लागू क्यों नहीं कर रहे हैं, और केवल ए/बी को वर्चुअल/अतिरंजित के रूप में चिह्नित कर रहे हैं? – YavgenyP

+0

@ ट्यूडर सी # में सोच रहा था लेकिन किसी ओओपी भाषा जो एकाधिक विरासत की अनुमति नहीं देता है ठीक है। –

उत्तर

3

खैर एक ही रास्ता मैं तुम्हें सी # में इसे प्राप्त करने देख सकते हैं/जावा रचना के द्वारा होता है: जो एक संकेत कैसे में जावा/सी # मैन्युअल रूप से इसे लागू करने के लिए हो सकता है। इस पर विचार करें:

class Foo { 

} 

interface A { 
    public void a(); 
} 

interface B { 
    public void b(); 
} 

class ImplA implements A { 
    @Override 
    public void a() { 
     System.out.println("a"); 
    } 
} 

class ImplB implements B { 
    @Override 
    public void b() { 
     System.out.println("b"); 
    } 
} 

class Bar extends Foo { 
    A a = new ImplA(); 

    public void a() { 
     a.a(); 
    } 
} 

class Baz extends Foo { 
    B b = new ImplB(); 

    public void b() { 
     b.b(); 
    }  
} 

class Qux extends Foo { 

    A a = new ImplA(); 
    B b = new ImplB(); 

    public void b() { 
     b.b(); 
    } 

    public void a() { 
     a.a();   
    }  
} 

अब Qux सामान्य विरासत के माध्यम से Foo के दोनों कार्यक्षमता लेकिन यह भी संरचना द्वारा A और B के कार्यान्वयन है।

1

इस भाषाओं लक्षण प्रदान करने में प्राप्त है (यहाँ: ):

class Foo { 
    def fooM() {} 
} 

trait A { 
    def aFunc() {} 
} 

trait B { 
    def bFunc() {} 
} 

class Bar extends Foo with A {} 

class Baz extends Foo with B {} 

class Qux extends Foo with A with B {} 

क्योंकि स्काला जावा (न एकाधिक वंशानुक्रम और न ही लक्षण वाले) यह कुछ इस तरह में अनुवाद किया है के शीर्ष पर चलता है (सरलीकृत) -

class Foo { 
} 

interface A { 
    void aFunc(); 
} 

interface B { 
    void bFunc(); 
} 

class Bar extends Foo implements A { 

    public void aFunc() { 
     $A.aFunc(); 
    } 
} 

class Baz extends Foo implements B { 

    public void bFunc() { 
     $B.bFunc(); 
    } 
} 

class Qux extends Foo implements A, B { 

    public void aFunc() { 
     $A.aFunc(); 
    } 

    public void bFunc() { 
     $B.bFunc(); 
    } 
} 

class $A { 

    public static void aFunc() {} 
} 

class $B { 

    public static void bFunc() {} 
} 
3

इसके लिए अधिक सामान्य शब्द Mixin है। कुछ भाषाएं स्कैला और डी जैसे बॉक्स से समर्थन प्रदान करती हैं। हालांकि अन्य भाषाओं में समान परिणाम प्राप्त करने के कई तरीके हैं।

सी # में एक छद्म-मिश्रण बनाने का एक तरीका है खाली इंटरफेस का उपयोग करना और विस्तार विधियों के साथ विधियां प्रदान करना।

interface A { } 
static class AMixin { 
    public static void aFunc(this A inst) { 
     ... //implementation to work for all A. 
    } 
} 

interface B { } 
static class BMixin { 
    public static void bFunc(this B inst) { 
     ... 
    } 
} 

class Qux : Foo, A, B { 
    ... 
} 
1

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

ठीक है, मैं प्यारAOP फ्रेमवर्क, और वे कई भाषाओं (सी # और जावा कई हैं) के लिए मौजूद हैं। एओपी फ्रेमवर्क मूल रूप से आपको अपनी विरासत संरचना में विभिन्न वर्गों में स्वयं निहित कार्यक्षमता जोड़ने की अनुमति देते हैं।

सी # के लिए, आपके पास PostSharp है और जावा के लिए आपके पास AspectJ है, कई अन्य लोगों के बीच।

कई एओपी ढांचे विरासत का उपयोग किये बिना 'अपहरण' या 'ओवरराइडिंग' विधि कॉल की अनुमति देते हैं।

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