स्काला में साथी वस्तुओं के पीछे तर्क क्या है?


107

क्या ऐसा मामला है जहां एक वर्ग के लिए एक साथी वस्तु (सिंगलटन) की आवश्यकता है? मैं एक वर्ग क्यों बनाना चाहता हूँ, कहो Fooऔर इसके लिए एक साथी वस्तु भी बनाऊँ?



यह भी देखें stackoverflow.com/a/9806136/736957 जो यहाँ उत्तरों का एक अच्छा संकलन है
हंसेलेडेलिक

जवाबों:


82

साथी ऑब्जेक्ट मूल रूप से एक जगह प्रदान करता है जहां कोई "स्थिर-जैसे" तरीके रख सकता है। इसके अलावा, एक साथी वस्तु, या साथी मॉड्यूल, निजी लोगों सहित वर्ग के सदस्यों के लिए पूर्ण पहुंच है।

साथी वस्तुएं फैक्ट्री के तरीकों जैसी चीजों को इनकैप्सुलेट करने के लिए बहुत अच्छी हैं। उदाहरण के लिए, Fooऔर FooFactoryहर जगह, आपके पास होने के बजाय , आपके पास एक कारखाना हो सकता है, जिस पर फैक्ट्री की ज़िम्मेदारियों के लिए एक साथी ऑब्जेक्ट होता है।


61

कंपेनियन ऑब्जेक्ट राज्य और विधियों को संग्रहीत करने के लिए उपयोगी होते हैं जो एक वर्ग के सभी उदाहरणों के लिए सामान्य होते हैं लेकिन वे स्थैतिक तरीकों या फ़ील्ड का उपयोग नहीं करते हैं। वे नियमित आभासी तरीकों का उपयोग करते हैं जो विरासत के माध्यम से ओवरराइड किए जा सकते हैं। स्काला के पास वास्तव में कुछ भी स्थिर नहीं है। आपके द्वारा इसका उपयोग करने के बहुत सारे तरीके हैं लेकिन यहां एक सरल उदाहरण है।

abstract class AnimalCounter
{
    var animals = 0

    def name: String

    def count()
    {
        animals += 1
        println("%d %ss created so far".format(animals, name))
    }
}

abstract class Animal
{
    def companion: AnimalCounter
    companion.count()
}

object Dog extends AnimalCounter
{
    val name = "dog"
}

class Dog extends Animal
{
    def companion = Dog
}

object Cat extends AnimalCounter
{
    val name = "cat"
}

class Cat extends Animal
{
    def companion = Cat
}

जो इस उत्पादन का उत्पादन करता है:

scala> new Dog
1 dogs created so far

scala> new Cat
1 cats created so far

scala> new Dog
2 dogs created so far

scala> new Cat
2 cats created so far

1
इसी तरह का दृष्टांत यहाँ भी पाया जा सकता है: daily-scala.blogspot.sk/2009/09/companion-object.html
xhudik

30

... और कक्षाओं के लिए स्थैतिक कारखाने के तरीकों (न कि डीपी) को संग्रहीत करने के लिए यह एक अच्छी जगह है। यदि आप उन ओवरलोड फैक्ट्री विधियों को नाम देते हैं (/ ... /) तो आप वर्ग बनाने / शुरू करने में सक्षम होंगे

  1. बिना 'नया' (वास्तव में उतना महत्वपूर्ण नहीं)

  2. मापदंडों के विभिन्न संभावित सेटों के साथ (तुलना करें कि बलोच टेलिस्कोपिंग कंस्ट्रक्टर के बारे में प्रभावी जावा में क्या लिखते हैं)

  3. यह तय करने की क्षमता के साथ कि आप किस व्युत्पन्न वर्ग के बजाय सार (साथ) बनाना चाहते हैं

उदाहरण कोड:

abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
  def apply(s: String) = {
    new RealThing(s)
  }
  def apply(i: Int) = {
    new AlternativeThing(i)
  }
}

// somewhere else you can
val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int

मैं ऑब्जेक्ट / बेस क्लास AbstractXxxxx नहीं कहूंगा क्योंकि यह बुरा नहीं लगता: जैसे कुछ अमूर्त बनाना। उन नामों को वास्तविक अर्थ दें। अपरिवर्तनीय, विधि कम, केस कक्षाओं का उपयोग करने पर विचार करें और अमूर्त आधार वर्ग को सील करें।


2
RealThingऔर AlternativeThingकक्षा में एक privateनिर्माता होना चाहिए जिसने उपयोगकर्ता को AbstractClassकारखाने का उपयोग करने के लिए मजबूर किया हो। class AlternativeThing private(i: Int) extends AbstractClass
15

@ [सिग्मोन जाचिम] स्काला एब्स्ट्रैक्ट क्लास मल्टीपल इनहेरिटेंस का समर्थन नहीं करता है। तो संकलक आपके मामले में इसकी अनुमति क्यों देता है?
user2441441

19

सायम ने अपने उत्तर में कही गई बातों के अलावा , स्काला संकलक भी संगत साथी वस्तुओं (या तो स्रोत या लक्ष्य) में प्रकारों के निहित रूपांतरणों की तलाश करता है, इसलिए रूपांतरणों को आयात करने की आवश्यकता नहीं है।

स्काला में सामान्य प्रोग्रामिंग में एकल वस्तुओं के कारण के बारे में कहते हैं:

जैसा कि अध्याय 1 में उल्लेख किया गया है, एक तरीका है जिसमें स्काला जावा की तुलना में अधिक ऑब्जेक्ट-ओरिएंटेड है कि स्काला में कक्षाओं में स्थिर सदस्य नहीं हो सकते हैं। इसके बजाय, स्काला में सिंगलटन ऑब्जेक्ट्स हैं (पृष्ठ 65)।


3

मैं हमेशा सहयोगी वस्तुओं को स्काला में कार्यात्मक और वस्तु उन्मुख कोड लिखने के लिए एक पुल के रूप में देखता हूं । कई बार हमें सिर्फ शुद्ध कार्यों की आवश्यकता होती है जो कुछ इनपुट लेते हैं और एक प्रोसेसिंग परिणाम प्रदान करते हैं। उन प्रासंगिक कार्यों को साथी ऑब्जेक्ट में डालने से अपने लिए और साथ ही मेरे कोड के शीर्ष पर कुछ एक इमारत को देखने और उपयोग करना आसान हो जाता है।

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


0

यदि आप एक ही नाम के साथ एक ही फ़ाइल में वर्ग और ऑब्जेक्ट को परिभाषित करते हैं, तो उन्हें साथी वर्ग और ऑब्जेक्ट के रूप में जाना जाता है। स्काला में JAVA कीवर्ड की तरह स्थिर नहीं है, आप स्काला में साथी वर्ग और ऑब्जेक्ट के साथ स्टेटिक के प्रतिस्थापन के रूप में ले सकते हैं।

अधिक विस्तार से जानकारी के लिए, कृपया आलेख क्लास और ऑब्जेक्ट कीवर्ड को स्कैला प्रोग्रामिंग में देखें


-1

सबसे पहले, यह स्टैटिक बनाम नॉन स्टेटिक मैथड मेथड्स का स्पष्ट पृथक्करण प्रदान करता है। एकल वर्ग बनाने के लिए एक सरल तरीका भी प्रदान करता है।

यह अन्य वर्गों और / या लक्षणों से विरासत में भी मिल सकता है, जो कि जावा स्थिर तरीकों से नहीं किया जा सकता है। और इसे एक पैरामीटर के रूप में पारित किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.