2012-06-30 14 views
14
scala> class C 
defined class C 

scala> class subC extends C 
defined class subC 

scala> class A { type T = C} 
defined class A 

scala> class subA extends A { override type T = subC} 
<console>:10: error: overriding type T in class A, which equals C; 
type T has incompatible type 
     class subA extends A { override type T = subC} 
             ^

उपरोक्त उदाहरण में, मैंने एक त्रुटि संदेश है कि मैं वर्ग A (भले ही चुना प्रकार subC वर्ग C फैली) में प्रकार क्षेत्र ओवरराइड नहीं कर सकते हो।क्या किसी प्रकार के फ़ील्ड को ओवरराइड करना संभव है?

एक प्रकार के क्षेत्र को ओवरराइड करना संभव है? और यदि हां, उपर्युक्त उदाहरण में क्या गलत है?

उत्तर

22

आप प्रकारों के संबंध में 'ओवरराइडिंग' की बात नहीं करेंगे, बल्कि को उनकी सीमाओं को संकुचित करते हैं।

  1. type T ... कोई सीमा नहीं
  2. type T <: C ... TC या C की एक उप-प्रकार है (जो कहा जाता है ऊपरी बाध्य)
  3. type T >: C ... TC या के एक महाप्रकार है C (जिसे निचला बाउंड कहा जाता है)
  4. type T = C ... T ठीक है C (प्रकार उर्फ)

इसलिए, यदि T विशेषता A का एक प्रकार सदस्य है, और SubAA की एक उप-प्रकार, इस मामले में (2) SubA एक और अधिक विशेष रूप से उप-प्रकार C करने के लिए T संकीर्ण हो सकता है, जबकि मामले में (3) यह C के उच्च सुपरटेप को संकीर्ण कर सकता है। केस (1) SubA के लिए कोई प्रतिबंध नहीं लगाता है, जबकि मामले (4) का अर्थ है कि T बोलने के लिए 'अंतिम' है।


यह A में T की useability कि क्या यह एक तरीका है तर्क के प्रकार या एक विधि की वापसी प्रकार के रूप में प्रकट हो सकता है के लिए परिणाम है।

उदाहरण:

trait C { def foo =() } 
trait SubC extends C { def bar =() } 

trait MayNarrow1 { 
    type T <: C // allows contravariant positions in MayNarrow1 
    def m(t: T): Unit = t.foo // ...like this 
} 

object Narrowed1 extends MayNarrow1 { 
    type T = SubC 
} 

object Narrowed2 extends MayNarrow1 { 
    type T = SubC 
    override def m(t: T): Unit = t.bar 
} 

यह है, क्योंकि प्रकार Tcontravariant स्थिति में होता है (एक विधि तर्क के प्रकार के रूप में) MayNarrow1 में विधि m परिभाषित करना संभव है इसलिए यह अभी भी भले ही T को संकुचित होता है मान्य है MayNarrow1 के उपप्रकार में (विधि निकाय t का इलाज कर सकता है जैसे कि यह C टाइप किया गया था)।

इसके विपरीत, type T = C अनिवार्य रूप से T को हल करता है, जो एक विधि final बनाने के अनुरूप होगा।T फिक्सिंग करके, यह एक covariant स्थिति में इस्तेमाल किया जा सकता है (एक विधि की वापसी प्रकार के रूप में):

trait Fixed extends MayNarrow1 { 
    type T = C // make that T <: C to see that it won't compile 
    final def test: T = new C {} 
} 

अब आप आसानी से देख सकते हैं कि यह आगे 'ओवरराइड' T करने के लिए मना किया जाना चाहिए:

trait Impossible extends Fixed { 
    override type T = SubC 

    test.bar // oops... 
} 

trait MayNarrow2 { 
    type T >: SubC // allows covariant positions in MayNarrow2 
    def test: T = new SubC {} 
} 

object Narrowed3 extends MayNarrow2 { 
    type T = C 
    test.foo 
} 

object Narrowed4 extends MayNarrow2 { 
    type T = C 
    override def test: T = new C {} 
} 
:

पूरा होने के लिए, यहाँ एक निचली सीमा के कम आम मामला है

+1

नोट: भिन्न प्रकार के सदस्यों के बीच सूक्ष्म अंतर के लिए भिन्नता के साथ सीमा बनाम टाइप पैरामीटर के साथ सूक्ष्म अंतर के लिए http://scala-programming-language.1934581.n4.nabble.com/Scala-type-override-td1943353 में जेफरी वॉशबर्न की पोस्ट देखें .html –

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

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