2008-11-04 13 views
14

जावा में मिश्रित या गुणों का अनुकरण करने का कोई तरीका है? मूल रूप से, मुझे एकाधिक विरासत करने का एक तरीका चाहिए ताकि मैं कई कक्षाओं में सामान्य व्यावसायिक तर्क जोड़ सकूंजावा लक्षण या मिश्रण पैटर्न?

उत्तर

12

मैं सभी व्यावसायिक तर्क को एक नई कक्षा BusinessLogic में समाहित कर दूंगा और प्रत्येक वर्ग को BusinessLogic कक्षा में कॉल करने की आवश्यकता है। आप अपनी कक्षाओं कि BusinessLogic को कॉल करने के लिए एक एकल जड़ें पदानुक्रम की जरूरत है, तो आप एक इंटरफेस बनाने के लिए और साथ ही होगा (BusinessLogicInterface?)

छद्म कोड में:

interface BusinessLogicInterace 
{ 
    void method1(); 
    void method2(); 
} 

class BusinessLogic implements BusinessLogicInterface 
{ 
    void method1() { ... } 
    void method2() { ... } 
} 

class User 
    extends OtherClass 
    implements BusinessLogicInterface 
{ 
    BusinessLogic logic = new BusinessLogic(); 

    @Override 
    void method1() { logic.method1(); } 

    @Override 
    void method2() { logic.method2(); } 
} 

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

+0

ठीक है, तो प्रतिनिधिमंडल का उपयोग करने और logic.method1, logic.method2, logic.method3 को स्पष्ट रूप से आमंत्रित करने से बचने के लिए कोई चाल नहीं है? यह टाइपिंग और बॉयलरप्लेट कोड पर सहेजने में मदद करेगा .. – joshjdevl

+1

@joshjdevl वहाँ हैं, लेकिन इसका मतलब है [कंपाइलर हैकिंग] (http://projectlombok.org/features/Delegate.html)। – maaartinus

3

एकाधिक विरासत के लिए जावा का उत्तर कई इंटरफेस को लागू करने की क्षमता है। बेशक, इसका मतलब है कि आपको विधि घोषणाएं मिलेंगी, लेकिन तर्क नहीं।

आप रचना द्वारा मिश्रित अनुकरण करने का प्रयास कर सकते हैं: आपकी जावा क्लास सदस्य चर को परिभाषित कर सकती है जो कुछ सामान्य व्यवसाय तर्क करने वाले अन्य वर्गों का प्रतिनिधित्व करती है।

जावा कक्षाओं को डिजाइन करने में, मुझे अपने वास्तुकला के डिजाइन को बाधित करने के लिए सी ++ शैली एकाधिक विरासत की कमी नहीं मिली है। आप जो करना चाहते हैं उसे हासिल करने के लिए आपको एक रास्ता मिलेगा।

17

जिस तरह से आप इसे करना नहीं चाहते हैं। Effective Java अनुशंसा करता है कि आप "विरासत पर संरचना का पक्ष लें"। मतलब है कि आप सामान्य तर्क को अन्य वर्गों और प्रतिनिधिमंडल में ले जाते हैं। इस तरह आप जावा में कई विरासत की कमी के आसपास आते हैं।

4

क्या ऑब्जेक्ट-प्यूरिस्ट आज आप में हलचल कर रहा है?

सोचें कि आप समग्र उन्मुख प्रोग्रामिंग के साथ क्या कर सकते हैं?

तो फिर तुम, श्रीमान, Apache Polygene (पूर्व Qi4J या जेस्ट) के लिए देख रहे हैं;)

+0

क्या यह गुणों या सिर्फ मिश्रणों का समर्थन करता है? अर्थात। जब समान हस्ताक्षर वाले दो तरीकों से एक विवाद बी/डब्ल्यू होता है, तो क्या कोई जीतता है, या यह एक कंपाइलर त्रुटि के रूप में दिखाई देता है और आपको संघर्ष को हल करने के लिए कुछ रास्ता देता है? –

+0

@NeilTraft विधि संकल्प अनुमानित है और घोषणा आदेशों पर आधारित है, http://qi4j.org/_core.html#core-api-mixin – eskatos

3

QI4J आप mixins

+0

देखें जो अब [अपाचे ज़ेस्ट] है (https://zest.apache.org /) –

+0

अपाचे ज़ेस्ट अब [अपाचे पॉलीजीन] (http://polygene.apache.org/) – Stuporman

0

सरल mixin को लागू करने का उपयोग करने की अनुमति देता/लक्षण जावा में समर्थन का उपयोग कर CGLib/javassit काफी है आसान। आप उदाहरण के लिए उदाहरण here उदाहरण के लिए देख सकते हैं। अधिक, पूर्ण समाधान का उपयोग करने के लिए तैयार पाया जा सकता है: here

2

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

जब कर के रूप में यहाँ How are Scala traits compiled into Java bytecode?

समझाया इस तरह स्काला लक्षण के लिए JVM कोड उत्पन्न करता है के समान है इस उदाहरण बन जाता है:

interface BusinessLogicInterface { 
    void method0(); 

    class DefaultImpl { 
     private DefaultImpl() { 
     } 

     public static void method1(BusinessLogicInterface self) { ... } 
     public static void method2(BusinessLogicInterface self) { ... } 
    } 

    void method1(); 
    void method2(); 
} 

class User extends OtherClass implements BusinessLogicInterface { 
    @Override 
    void method0() { ... } 

    @Override 
    void method1() { BusinessLogic.defaultImpl.method1(this); } 

    @Override 
    void method2() { BusinessLogic.defaultImpl.method2(this); } 
} 

ध्यान दें कि हम के रूप में इंटरफ़ेस प्रकार का ऑब्जेक्ट पारित "स्वयं" पैरामीटर। इसका मतलब है कि व्यापार तर्क अन्य सार तरीकों (method0) का उपयोग कर सकते हैं।यह सार तत्वों के साथ एक विशेषता बनाने के लिए बहुत उपयोगी हो सकता है जो सभी ऑर्थोगोनल एक-दूसरे के लिए हैं और उपयोगिता "विस्तार" विधियों को इन ऑर्थोगोनल तरीकों के संदर्भ में लागू किया जा सकता है।

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

+0

ध्यान दें कि जावा 8 में "वर्चुअल एक्सटेंशन विधियां" होंगी जो वास्तव में अधिक आसानी से सक्षम हो जाएंगी। –

0

जावा -8 के अनुसार, डिफ़ॉल्ट इंटरफ़ेस विधियों को जोड़ा गया था। यह, जावा में इंटरफेस के एकाधिक विरासत के साथ मिलकर कुछ प्रकार के मिश्रण की अनुमति देनी चाहिए। स्पष्ट रूप से इंटरफेस को स्वतंत्र रूप से काम करना पड़ता है। तो, महत्वपूर्ण सीमाएं होंगी।

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