खोज…


वाक्य - विन्यास

  • विशेषता एटीट्यूड {...}
  • क्लास एच्लास (...) का विस्तार एटरेट {...}
  • क्लास AClass Brait को ATrait के साथ विस्तारित करता है
  • क्लास AClass BTrait के साथ ATrait फैली हुई है
  • क्लास एटलस ने जलसन्धि को जलडमरूमध्य के साथ जलडमरूमध्य के साथ विस्तारित किया
  • क्लास एट्रेट, BTrait का विस्तार करता है

लक्षण के साथ स्थिर संशोधन

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

निम्नलिखित उदाहरण से पता चलता है कि लक्षण कैसे स्टैक किए जा सकते हैं। लक्षणों का क्रम महत्वपूर्ण है। लक्षणों के विभिन्न क्रमों का उपयोग करके, अलग व्यवहार प्राप्त किया जाता है।

class Ball {
  def roll(ball : String) = println("Rolling : " + ball)
}

trait Red extends Ball {
  override def roll(ball : String) = super.roll("Red-" + ball)
}

trait Green extends Ball {
  override def roll(ball : String) = super.roll("Green-" + ball)
}

trait Shiny extends Ball {
  override def roll(ball : String) = super.roll("Shiny-" + ball)
}

object Balls {
  def main(args: Array[String]) {
    val ball1 = new Ball with Shiny with Red
    ball1.roll("Ball-1") // Rolling : Shiny-Red-Ball-1

    val ball2 = new Ball with Green with Shiny
    ball2.roll("Ball-2") // Rolling : Green-Shiny-Ball-2
  }
}

ध्यान दें कि super का उपयोग दोनों लक्षणों में roll() पद्धति को लागू करने के लिए किया जाता है। केवल इस तरह से हम स्टैकेबल मॉडिफिकेशन प्राप्त कर सकते हैं। स्टैकेबल मॉडिफिकेशन के मामलों में, विधि मंगलाचरण आदेश रैखिककरण नियम द्वारा निर्धारित किया जाता है।

विशेषता मूल बातें

यह स्काला में एक विशेषता का सबसे मूल संस्करण है।

trait Identifiable {
  def getIdentifier: String
  def printIndentification(): Unit = println(getIdentifier)
}

case class Puppy(id: String, name: String) extends Identifiable {
  def getIdentifier: String = s"$name has id $id"
}

चूंकि Identifiable लिए कोई सुपर क्लास घोषित नहीं की गई है, डिफ़ॉल्ट रूप से यह AnyRef वर्ग से फैली हुई है। क्योंकि getIdentifier लिए कोई परिभाषा Identifiable में प्रदान नहीं की गई है, Puppy वर्ग को इसे लागू करना चाहिए। हालाँकि, Puppy ने Identifiable से printIdentification के कार्यान्वयन को विरासत में printIdentification है।

REPL में:

val p = new Puppy("K9", "Rex")
p.getIdentifier  // res0: String = Rex has id K9
p.printIndentification()  // Rex has id K9

डायमंड की समस्या का समाधान

हीरे की समस्या , या कई विरासत, स्कैल द्वारा ट्रेट्स का उपयोग करके नियंत्रित किया जाता है, जो जावा इंटरफेस के समान हैं। लक्षण इंटरफेस की तुलना में अधिक लचीले हैं और कार्यान्वित विधियों को शामिल कर सकते हैं। यह अन्य भाषाओं में मिक्सिन्स के समान लक्षण बनाता है।

स्काला कई वर्गों से विरासत का समर्थन नहीं करता है, लेकिन एक उपयोगकर्ता एक ही वर्ग में कई लक्षणों का विस्तार कर सकता है:

trait traitA {
  def name = println("This is the 'grandparent' trait.")
}

trait traitB extends traitA {
  override def name = {
    println("B is a child of A.")
    super.name
  }

}

trait traitC extends traitA {
  override def name = {
    println("C is a child of A.")
    super.name
  }
}

object grandChild extends traitB with traitC

grandChild.name

यहाँ grandChild को traitB और traitC दोनों से विरासत में traitC , जो बदले में दोनों traitA से विरासत में traitA । आउटपुट (नीचे) पूर्ववर्ती के क्रम को भी दर्शाता है जब यह हल किया जाता है कि किस विधि कार्यान्वयन को पहले कहा जाता है:

C is a child of A. 
B is a child of A. 
This is the 'grandparent' trait.

ध्यान दें कि, जब super का उपयोग class या trait में तरीकों को लागू करने के लिए किया जाता है, तो कॉल पदानुक्रम को तय करने के लिए रैखिककरण नियम लागू होता है। grandChild लिए grandChild आदेश होगा:

grandChild -> traitC -> traitB -> traitA -> AnyRef -> कोई भी


नीचे एक और उदाहरण दिया गया है:

trait Printer {
  def print(msg : String) = println (msg)
}

trait DelimitWithHyphen extends Printer {
  override def print(msg : String) {
    println("-------------")
    super.print(msg)
  }
}

trait DelimitWithStar extends Printer  {
  override def print(msg : String) {
    println("*************")
    super.print(msg)
  }
}

class CustomPrinter extends Printer with DelimitWithHyphen with DelimitWithStar

object TestPrinter{
  def main(args: Array[String]) {
    new CustomPrinter().print("Hello World!")
  }
}

यह कार्यक्रम प्रिंट करता है:

*************
-------------
Hello World!

CustomPrinter लिए CustomPrinter होगा:

कस्टमप्रिन्टर -> डेलिमिटविथस्टार -> डेलिमिटविथहेनफेन -> प्रिंटर -> AnyRef -> कोई भी

linearization

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

class Shape {
  def paint (shape: String): Unit = {
    println(shape)
  }
}

trait Color extends Shape {
  abstract override def paint (shape : String) {
    super.paint(shape + "Color ")
  }
}

trait Blue extends Color {
  abstract override def paint (shape : String) {
    super.paint(shape + "with Blue ")
  }
}

trait Border extends Shape {
  abstract override def paint (shape : String) {
    super.paint(shape + "Border ")
  }
}

trait Dotted extends Border {
  abstract override def paint (shape : String) {
    super.paint(shape + "with Dotted ")
  }
}

class MyShape extends Shape with Dotted with Blue {
  override def paint (shape : String) {
    super.paint(shape)
  }
}

रैखिककरण आगे से पीछे होता है। इस मामले में,

  1. पहले Shape को रैखिक बनाया जाएगा, जो दिखता है:

    Shape -> AnyRef -> Any

  2. फिर Dotted होता है:

    Dotted -> Border -> Shape -> AnyRef -> Any

  3. अगली पंक्ति में Blue । आम तौर पर Blue का रैखिककरण होगा:

    Blue -> Color -> Shape -> AnyRef -> Any

    क्योंकि, MyShape के अब तक ( 2 चरण ) के Shape -> AnyRef -> Any , Shape -> AnyRef -> Any भी पहले ही प्रकट हो चुका है। इसलिए, इसे अनदेखा किया जाता है। इस प्रकार, Blue रेखीयकरण होगा:

    Blue -> Color -> Dotted -> Border -> Shape -> AnyRef -> Any

  4. अंत में, Circle जोड़ा जाएगा और अंतिम रैखिककरण आदेश होगा:

    सर्कल -> नीला -> रंग -> बिंदीदार -> सीमा -> आकार -> AnyRef -> कोई भी

यह रैखिककरण आदेश किसी भी वर्ग या विशेषता में super का उपयोग किए जाने पर तरीकों के आह्वान के आदेश को तय करता है। दाईं ओर से पहली विधि के कार्यान्वयन को रैखिककरण क्रम में लागू किया जाता है। यदि new MyShape().paint("Circle ") निष्पादित होता है, तो यह प्रिंट होगा:

Circle with Blue Color with Dotted Border 

रैखिककरण पर अधिक जानकारी यहां पाई जा सकती है



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow