2010-11-26 11 views
5

विरासत व्यक्त करने के लिए अलग-अलग नोटेशन क्यों हैं? जेनेरिक में मुझे < का उपयोग करना होगा: -ऑपरेटर - सामान्य श्रेणी-विरासत में मुझे विस्तारित कीवर्ड का उपयोग करना होगा।विरासत को व्यक्त करने के लिए अलग-अलग नोटेशन

उदाहरण के लिए मैं इस बारे में करने के लिए है:

class X[A <: B] <: Y 

या

class X[A extends B] extends Y // like Java 

मैं वर्तमान अंकन के साथ कोई समस्या नहीं है:

class X[A <: B] extends Y 

लेकिन कुछ इस तरह नहीं लिख , लेकिन मैं जानना चाहता हूं कि जेनरिक के प्रकार पदानुक्रम को अलग तरीके से नोट करने का कोई कारण है या नहीं।

उत्तर

12

ठीक है, वहाँ कुछ भी नहीं ऐसा करने से स्काला रोक है, लेकिन, तथ्य की बात के रूप में, वे सब पर एक ही बात व्यक्त नहीं करते । और, वास्तव में, आप देख सकते हैं कि जावा में, जहां आप X super Y लिख सकते हैं, लेकिन आप class X super Y नहीं कह सकते हैं।

कीवर्ड extendsकक्षा, विरासत में से एक के बीच संबंध व्यक्त करता है। दूसरी तरफ, <: और >:प्रकार, सीमाओं में से एक के बीच संबंध व्यक्त करें। जब मैं X <: Y कहता हूं, तो यह X और Y दोनों के लिए String होने के लिए मान्य है, उदाहरण के लिए, String extends String अर्थहीन होगा। यह भी मामला है कि List[String] <: List[AnyRef], फिर भी, List[String] extends List[AnyRef] व्यर्थ है। और, बस बिंदु बनाने के लिए, यह सच है कि Set[String] <: Set[AnyRef]। इन सभी उदाहरणों में मैंने अभी दिया है कि हम उसी वर्ग के बारे में बात कर रहे हैं, लेकिन आवश्यक नहीं, टाइप करें।

और, निश्चित रूप से, दृश्य सीमाओं (<%) और संदर्भ सीमाओं (:) के बीच अन्य संबंध हैं।

तो, सिर्फ इसलिए कि extends तात्पर्य <:, यह पालन नहीं करता है कि <: तात्पर्य extends है, जो, अकेले, कारण पर्याप्त एक ही कीवर्ड का उपयोग कर से बचने के लिए है। उसमें अन्य प्रकारों के बीच संबंध जोड़ें, और आपके पास बहुत अधिक बंद सौदा है।

+1

कक्षाओं और प्रकारों –

+0

के बीच अंतर के बारे में बात करने के लिए कक्षाओं और प्रकारों के बारे में बात करने के लिए अलग-अलग चीजों के रूप में अलग-अलग टिप्पणियों का उपयोग करने के लिए यह समझ में आता है। स्पष्टीकरण के लिए धन्यवाद। – sschaef

7

जब आप विस्तारित करते हैं तो यह थोड़ा और स्पष्ट हो जाता है (कोई भी इरादा नहीं) आपके उदाहरण को एक साधारण मामले से परे।

एकाधिक वंशानुक्रम:

class C[A] extends X with Y with Z 

mixins:

val x = new X with Y 

Parameterization:

class X[A <: B] extends Y[A] 

एकाधिक (संबंधित) टाइप पैरामीटर:

class X[A >: B, B](x: A, xs: Seq[B]) 
,210

प्रसंग सीमा:

class X[A : Manifest] 

देखें सीमा:

class X[A <% Ordered[A]] 

जेनेरिक तरीके:

class Foo[B] { 
    def bar[A <: B](x: A) = ... 
} 

आप देख सकते हैं, रिश्ते है कि एक प्रकार पैरामीटर में निर्दिष्ट किया जा सकता एक वर्ग घोषित करते समय उपलब्ध सरल रैखिक पदानुक्रम से कहीं अधिक समृद्ध हैं, खासकर जब आप अल सीमाओं के लिए कम।

यह भी ध्यान देने योग्य बात है कि वर्ग या तरीकों के लिए सामान्य प्रकार पैरामीटर बहुत बार अनुमान लगाया जा होगा, आप लिखने के लिए अनुमति देता है लायक है:

val myList = List(1, 2, 3) 
बजाय

val myList = List[Int](1, 2, 3) 

तो जिस तरह अंकन उपयोग किया जाता है बहुत अलग है।

अद्यतन

एक विशिष्ट उदाहरण सिर्फ दिमाग में वसंत है, एक साथ दोनों अंकन का उपयोग प्रदर्शन और दिखा कि वे किस तरह अलग रहने के लिए की जरूरत है:

def someMethod[T <: Foo with Bar](x: T) = ... 

यह जरूरी है कि टाइप परम TFoo और Bar दोनों में मिश्रित कुछ उपप्रकार बनें।

ही संरचनात्मक प्रकार के साथ लागू होता है:

type Closable = { def close: Unit } //alias for a structural type 
def someMethod[T <: Closable](x: T) = ... 
संबंधित मुद्दे