2013-01-05 20 views
6

के साथ ट्राइट मिक्सिन मेरे पास एक सार आधार वर्ग (Base) है जिसमें इसके लिए परिभाषित कुछ स्टैकिंग गुण हैं (StackingTrait)।स्कैला: सार बेस क्लास

trait Base { 
    def foo 
} 
trait StackingTrait extends Base { 
    abstract override def foo { super.foo } 
} 

यह बहुत एक उपवर्ग निम्न सिंटैक्स का उपयोग कर लागू करने के लिए सुविधाजनक होगा, लेकिन यह काम नहीं करता क्योंकि संकलक का कहना है कि foo override और उसके बाद के साथ घोषित किए जाने की आवश्यकता abstract override recompile, जो क्योंकि अमान्य है पर साथ Impl एक कक्षा है।

class Impl extends Base with StackingTrait { 
    def foo {} 
} 

मैं इस तरह के वाक्यविन्यास को अस्वीकार करने का एक अच्छा कारण नहीं सोच सकता; foo को Impl के साथ तार्किक रूप से परिभाषित किया गया है ताकि यह निर्धारित किया जा सके कि स्टैकिंग अवधारणात्मक रूप से वही है।

नोट: मुझे यह कामकाज पता चला है जो प्रभावी रूप से वही काम करेगा जो मुझे चाहिए, लेकिन एक सहायक वर्ग की आवश्यकता मुझे बेहतर समाधान चाहती है।

class ImplHelper extends Base { 
    def foo {} 
} 
class Impl extends ImplHelper with StackingTrait 

वांछित वाक्यविन्यास संकलित क्यों नहीं होता है और क्या कोई सुरुचिपूर्ण समाधान है?

उत्तर

4

मेरी समझ यह है कि त्रुटि संदेश भ्रमित हो सकता है, व्यवहार सही है। fooStackingTrait में abstract override के रूप में घोषित किया जाता है, और इस तरह कोई ठोस वर्ग कि घुलमिल StackingTrait एक ठोस (नहीं abstract के रूप में चिह्नित) fooके कार्यान्वयन से पहले होना चाहिए मेंStackingTrait (linearization आदेश के सापेक्ष)। ऐसा इसलिए है क्योंकि super रैखिकरण आदेश में पहले से ही विशेषता को संदर्भित करता है, इसलिए foo के StackingTrait में मिश्रित होने से पहले निश्चित रूप से super.foo पर एक ठोस कार्यान्वयन की आवश्यकता है, या super.foo गैरकानूनी होगा।

जब आप ऐसा करते: - StackingTrait < - Impl

class Impl extends Base with StackingTrait { 
    def foo {} 
} 

linearization आदेश Base < है। StackingTrait से पहले एकमात्र विशेषता Base और Basefoo के ठोस कार्यान्वयन को परिभाषित नहीं करती है।

लेकिन जब आप ऐसा करते हैं:

traitImplHelper extends Base { 
    def foo {} 
} 
class Impl extends ImplHelper with StackingTrait 

linearization आदेश हो जाता है: Base <-ImplHelper <-StackingTrait <-Impl यहाँ ImplHelperfoo का एक ठोस परिभाषा शामिल है, औरStackingTrait से पहले निश्चित रूप से है।

यदि आप (class Impl extends StackingTrait with ImplHelper में) के बाद ImplHelper मिश्रित किया गया था, तो आपको एक ही समस्या होगी और यह संकलन करने में विफल रहेगा।

तो, यह मेरे लिए काफी अनुकूल है। मुझे आपके द्वारा संकलित करने के तरीके के बारे में पता नहीं है।हालांकि अगर आप Impl लिखने में आसान हैं और foo को अलग वर्ग/विशेषता की आवश्यकता के बिना वहां परिभाषित करने में सक्षम हैं) Base या StackingTrait लिखना आसान बनाने के बजाय, आप अभी भी यह कर सकते हैं:

trait Base { 
    protected def fooImpl 
    def foo { fooImpl } 
} 
trait StackingTrait extends Base { 
    abstract override def foo { super.foo } 
} 

class Impl extends Base with StackingTrait { 
    protected def fooImpl {} 
} 

बस मूल संस्करण की तरह आप foo (fooImpl के रूप में) को लागू करने के लिए प्रत्येक ठोस वर्ग को मजबूर करते हैं और इस बार यह संकलित करता है। यहां नकारात्मकता यह है कि fooImpl को super.foo पर कॉल नहीं करना चाहिए (यह कोई समझ नहीं आता है और अनंत लूप में जाएगा), संकलक आपको इसके बारे में चेतावनी नहीं देगा।

+0

शानदार उत्तर! मैं इस परिदृश्य के बारे में एक प्रश्न पोस्ट करने वाला था। धन्यवाद! –

+0

मुझे अभी भी इस समस्या का सामना करना पड़ा है। रैखिकरण अंततः इसके बारे में सही है, लेकिन मुझे एहसास हुआ कि लक्षणों को ढेर करने का वास्तविक विश्व उद्देश्य यह है: आप केवल सामान्य अमूर्त वर्ग/विशेषता के मौजूदा ठोस कार्यान्वयन के लिए एक स्टैकिंग विशेषता के साथ संशोधन कर सकते हैं। अर्थात। एक 'अमूर्त वर्ग सूची' है और एक 'विशेषता मॉड सूची सूची बढ़ाता है'। आप सिर्फ 'कक्षा फू मॉड के साथ सूची विस्तारित नहीं' लिख सकते हैं। सबसे पहले, आपको एक कंक्रीट सूची होना चाहिए, जैसे 'क्लास लिंक्डलिस्ट सूची' बढ़ाता है, फिर आप 'क्लास बार' लिंक्डलिस्ट को मॉड के साथ बढ़ा सकते हैं 'लिख सकते हैं। उम्मीद है कि समझ में आता है। –

+0

मैं यह जोड़ना भूल गया कि यह स्पष्ट रूप से स्पष्ट होने के लिए 'अमूर्त ओवरराइड' विधियों के साथ केवल एक ही चिंताओं के लक्षण हैं। ऐसी विधियों के बिना ऐसा लगता है कि लक्षणों को स्वतंत्र रूप से मिश्रित किया जा सकता है। –

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