2009-09-08 7 views
16

स्काला में मैं यह कर सकता:स्काला एक वर के साथ एक गैर सार डीईएफ़ अधिभावी

trait SomeTrait { 
    protected def foo: String 
} 

class Wibble extends SomeTrait { 
    protected var foo = "Hello" 
} 

लेकिन मैं एक ही बात है जहाँ मैं foo

trait SomeTrait { 
    protected def foo: String = "World" 
} 

class Wibble extends SomeTrait { 
    protected var foo = "Hello" //complains about lack of override modifier 

    override protected var foo = "Hello" //complains "method foo_ overrides nothing" 
} 

क्यों इसके लिए एक सामान्य परिभाषा प्रदान नहीं कर सकते क्या मैं यह नहीं कर सकता

संपादित करें: स्केला-उन पर एक बातचीत में मेलिंग सूची के बाद, मैं raised this in trac

उत्तर

19

स्काला में, जब आप एक var foo लिखते हैं, स्काला संकलक स्वचालित रूप से एक सेटर (foo_= कहा जाता है) और एक गेटर (उत्पन्न करता है foo कहा जाता है) इसके लिए, और फ़ील्ड को निजी के रूप में सेट करता है (यदि आप javap के साथ 'सार्वजनिक' स्कैला फ़ील्ड वाले क्लास को डीकंपाइल करते हैं तो आप इसे निजी के रूप में देखेंगे। यही तरीका है 'विधि foo_ = कुछ भी ओवरराइड नहीं करता' त्रुटि का मतलब है। आपकी विशेषता में आपने foo_= विधि को परिभाषित नहीं किया है, और सार्वजनिक क्षेत्र के सेटटर और गेटर्स हमेशा जोड़े में आते हैं।

यदि आप विशेषता (यानी अमूर्त विधि) में डिफ़ॉल्ट मान प्रदान नहीं करते हैं, तो override कीवर्ड आवश्यक नहीं है। इसलिए, आपके पहले उदाहरण में, गेटर अमूर्त विधि और सेटर को ओवरराइड करता है ... यह बस वहां है। संकलक शिकायत नहीं करता है। लेकिन जब आप विशेषता में विधि का वास्तविक कार्यान्वयन प्रदान करते हैं, तो आपको ओवरराइड करते समय विशेष रूप से override कीवर्ड लिखना होगा। protected var foo लिखते समय, आपने override कीवर्ड को गेटटर के लिए निर्दिष्ट नहीं किया है और override protected var foo लिखते समय, आपने संकलक को भी संकेत दिया है कि foo_= विधि को ओवरराइड किया जाना है, लेकिन विशेषता में ऐसी कोई विधि नहीं है।

इसके अलावा, तर्कसंगत रूप से आप def को var के साथ वास्तव में ओवरराइड नहीं कर सकते हैं (पिछले पैराग्राफ की तरह ओवरराइडिंग के सख्त दृश्य पर विचार करते हुए)। एक def तर्कसंगत रूप से एक फ़ंक्शन है (आप इसे कुछ इनपुट देते हैं, यह आउटपुट उत्पन्न करता है)। एक var नो-एर्ग फ़ंक्शन के समान है, लेकिन किसी अन्य चीज़ के लिए अपना मान सेट करने का भी समर्थन करता है, एक ऑपरेशन जो फ़ंक्शन द्वारा समर्थित नहीं है। इसके बजाय, यदि आप इसे val पर बदल देंगे, तो यह ठीक होगा। यह एक ऐसे फ़ंक्शन की तरह है जो हमेशा एक ही (कैश्ड) परिणाम उत्पन्न करता है।

आप एक var आप कुछ इस तरह कर सकता है के लिए इसी तरह व्यवहार करना चाहते हैं (स्पष्ट सेटर और ही टिककर खेल होने से):

class Wibble extends SomeTrait { 
    private var bar = "Hello" 
    override protected def foo = bar 
    protected def foo_=(v: String) { bar = v} 
} 

अब आप कुछ भी आप एक वर :) के साथ कर सकता कर सकते हैं।

val x = new Wibble 
println(x.foo) // yields "Hello" 
x.foo = "Hello again" 
println(x.foo) // yields "Hello again" 
+0

क्षमा करें - मैंने एक त्रुटि की - मूल विशेषता विधि को भी संरक्षित किया जाना चाहिए था। मुझे यकीन नहीं है कि मैं आपके साथ 'var' के साथ' def' को ओवरराइड करने में असमर्थ होने के बारे में सहमत हूं। मेरे सभी 'डीफ' कह रहे हैं कि मैं उम्मीद करता हूं कि वहां 'फू' नामक एक एक्सेसर होगा जो एक स्ट्रिंग देता है - 'var' घोषित करना इस –

+0

का कार्यान्वयन है, मुझे लगता है कि मैं आपके साथ सहमत हूं। जब मैंने जवाब लिखा था तो मैं एक कठोर धारणा के रूप में ओवरराइड करने की सोच रहा था। मैं जवाब संपादित करूंगा, और एक व्यावहारिक समाधान प्रदान करूंगा :)। –

+0

यह एक शर्म की बात है कि 'ओवरराइड डीफ़' var' वाक्यविन्यास नहीं है –

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