जवाबों:
मैं दो अंतरों के बारे में सोच सकता हूं
स्कैला में प्रोग्रामिंग में एक सेक्शन है "To trait, or not to trait?" जो इस प्रश्न को संबोधित करता है। चूँकि 1 एड ऑनलाइन उपलब्ध है, मुझे उम्मीद है कि यहाँ पूरी बात उद्धृत करना ठीक है। (किसी भी गंभीर स्काला प्रोग्रामर को पुस्तक खरीदनी चाहिए):
जब भी आप व्यवहार के एक पुन: प्रयोज्य संग्रह को लागू करते हैं, तो आपको यह तय करना होगा कि आप किसी विशेषता या सार वर्ग का उपयोग करना चाहते हैं। कोई ठोस नियम नहीं है, लेकिन इस खंड में विचार करने के लिए कुछ दिशानिर्देश हैं।
यदि व्यवहार का पुन: उपयोग नहीं किया जाएगा , तो इसे एक ठोस वर्ग बनाएं। यह सब के बाद पुन: प्रयोज्य व्यवहार नहीं है।
यदि इसे कई, असंबद्ध वर्गों में पुन: उपयोग किया जा सकता है , तो इसे एक विशेषता बनाएं। केवल लक्षणों को वर्ग पदानुक्रम के विभिन्न भागों में मिलाया जा सकता है।
यदि आप जावा कोड में इसे प्राप्त करना चाहते हैं , तो एक सार वर्ग का उपयोग करें। चूंकि कोड वाले लक्षणों में एक करीबी जावा एनालॉग नहीं है, इसलिए यह जावा वर्ग में एक विशेषता से प्राप्त होने के लिए अजीब है। इस बीच, एक स्काला क्लास से इनहेरिट करना, बिल्कुल एक जावा क्लास से विरासत में मिलने जैसा है। एक अपवाद के रूप में, केवल सार सदस्यों के साथ एक स्कैला लक्षण सीधे एक जावा इंटरफ़ेस में अनुवाद करता है, इसलिए आपको ऐसे लक्षणों को परिभाषित करने के लिए स्वतंत्र महसूस करना चाहिए, भले ही आप जावा कोड से इसे विरासत में लेने की उम्मीद करें। जावा और स्काला के साथ काम करने के बारे में अधिक जानकारी के लिए अध्याय 29 देखें।
यदि आप इसे संकलित रूप में वितरित करने की योजना बनाते हैं , और आप बाहरी समूहों से यह अपेक्षा करते हैं कि वे इससे प्राप्त होने वाली कक्षाएं लिखें, तो आप एक अमूर्त वर्ग का उपयोग करने की ओर झुक सकते हैं। मुद्दा यह है कि जब कोई लाभ प्राप्त करता है या किसी सदस्य को खो देता है, तो इससे प्राप्त होने वाले किसी भी वर्ग को फिर से स्थापित किया जाना चाहिए, भले ही वे बदल नहीं गए हों। यदि बाहर के ग्राहक केवल व्यवहार में आएंगे, बजाय उससे विरासत में मिले, तो एक विशेषता का उपयोग करना ठीक है।
यदि दक्षता बहुत महत्वपूर्ण है , तो कक्षा का उपयोग करने की ओर झुकें। अधिकांश जावा रनटाइम एक क्लास मेम्बर का इनविटेशन मेथड इनवॉइस मेथड इनवोकेशन विधि की तुलना में एक तेज ऑपरेशन बनाते हैं। लक्षण इंटरफेस के लिए संकलित हो जाते हैं और इसलिए ओवरहेड को थोड़ा सा प्रदर्शन कर सकते हैं। हालाँकि, आपको यह चुनाव तभी करना चाहिए, जब आप यह जानते हों कि प्रश्न में विशेषता एक प्रदर्शन अड़चन है और इस बात के सबूत हैं कि वास्तव में समस्या का हल करने के बजाय कक्षा का उपयोग करना है।
यदि आप अभी भी नहीं जानते हैं, तो उपरोक्त पर विचार करने के बाद, फिर इसे एक लक्षण के रूप में बनाना शुरू करें। आप इसे हमेशा बाद में बदल सकते हैं, और सामान्य रूप से एक विशेषता का उपयोग करके अधिक विकल्प खुले रखते हैं।
जैसा कि @ मुश्ताक अहमद ने उल्लेख किया है, किसी गुण को किसी वर्ग के प्राथमिक निर्माता को पारित नहीं किया जा सकता है।
एक और अंतर इसका इलाज है super
।
वर्गों और लक्षणों के बीच दूसरा अंतर यह है कि कक्षाओं में,
super
कॉल सांख्यिकीय रूप से बाध्य होते हैं, लक्षणों में, वे गतिशील रूप से बाध्य होते हैं। यदि आपsuper.toString
एक कक्षा में लिखते हैं , तो आप ठीक से जानते हैं कि किस विधि को लागू किया जाएगा। जब आप एक विशेषता में एक ही बात लिखते हैं, हालांकि, जब आप विशेषता को परिभाषित करते हैं तो सुपर कॉल के लिए आह्वान करने के लिए विधि कार्यान्वयन अपरिभाषित होता है।
अधिक जानकारी के लिए अध्याय 12 के बाकी हिस्सों को देखें।
1 संपादित करें (2013):
लक्षण की तुलना में अमूर्त वर्गों के व्यवहार के तरीके में एक सूक्ष्म अंतर है। रैखिककरण नियमों में से एक यह है कि यह वर्गों की वंशानुगत पदानुक्रम को संरक्षित करता है, जो बाद में श्रृंखला में अमूर्त वर्गों को आगे बढ़ाता है जबकि लक्षण खुशी से मिश्रित हो सकते हैं। कुछ परिस्थितियों में, यह वास्तव में वर्ग रेखीयकरण के बाद की स्थिति में होना बेहतर होता है। , इसलिए अमूर्त वर्गों को इसके लिए इस्तेमाल किया जा सकता है। स्काला में वर्ग रेखीयकरण (मिक्सिन ऑर्डर) के लिए विवश देखें ।
2 संपादित करें (2018):
स्कला 2.12 के अनुसार, ट्रिट की द्विआधारी संगतता व्यवहार बदल गया है। २.१२ से पहले, सभी वर्गों में आवश्यक परिवर्तन के लिए सदस्य को जोड़ने या हटाने के लिए, जो वर्ग को परिवर्तित नहीं करता है, भले ही गुण को विरासत में मिला हो। इसका कारण है कि जिस तरह से जेवीएम में लक्षण अंकित किए गए थे।
स्कैला 2.12 के अनुसार, लक्षण जावा इंटरफेस को संकलित करते हैं , इसलिए आवश्यकता को थोड़ा आराम दिया गया है। यदि लक्षण निम्नलिखित में से कोई करता है, तो उसके उपवर्गों को अभी भी पुन: प्राप्ति की आवश्यकता होती है:
- परिभाषित फ़ील्ड (
val
याvar
, लेकिन एक निरंतर ठीक है -final val
परिणाम प्रकार के बिना)- बुला
super
- शरीर में इनिशाइज़र स्टेटमेंट
- एक वर्ग का विस्तार
- सही सुपरसट्रेट में कार्यान्वयन खोजने के लिए रैखिककरण पर निर्भर
लेकिन अगर विशेषता नहीं है, तो आप अब इसे बाइनरी संगतता को तोड़ने के बिना अपडेट कर सकते हैं।
If outside clients will only call into the behavior, instead of inheriting from it, then using a trait is fine
- क्या कोई समझा सकता है कि यहाँ क्या अंतर है? extends
बनाम with
?
extends
और के बीच कोई शब्दार्थ अंतर नहीं है with
। यह विशुद्ध रूप से वाक्यात्मक है। यदि आप कई टेम्प्लेट से विरासत में प्राप्त करते हैं, तो पहला मिलता है extend
, अन्य सभी को मिलता है with
, बस। with
एक अल्पविराम के रूप में सोचो class Foo extends Bar, Baz, Qux
:।
जो कुछ भी इसके लायक है, स्काला में ओडस्की एट अल के प्रोग्रामिंग की सिफारिश है कि, जब आप संदेह करते हैं, तो आप लक्षण का उपयोग करते हैं। आप हमेशा जरूरत पड़ने पर उन्हें बाद में अमूर्त कक्षाओं में बदल सकते हैं।
इस तथ्य के अलावा कि आप सीधे कई अमूर्त वर्गों का विस्तार नहीं कर सकते हैं, लेकिन आप एक वर्ग में कई लक्षणों को मिला सकते हैं, यह ध्यान देने योग्य है कि लक्षण स्टैकेबल हैं, क्योंकि किसी विशेषता में सुपर कॉल गतिशील रूप से बाध्य हैं (यह एक वर्ग या विशेषता का उल्लेख कर रहा है) वर्तमान वाला)।
सार वर्ग और विशेषता के बीच अंतर में थॉमस के जवाब से :
trait A{
def a = 1
}
trait X extends A{
override def a = {
println("X")
super.a
}
}
trait Y extends A{
override def a = {
println("Y")
super.a
}
}
scala> val xy = new AnyRef with X with Y
xy: java.lang.Object with X with Y = $anon$1@6e9b6a
scala> xy.a
Y
X
res0: Int = 1
scala> val yx = new AnyRef with Y with X
yx: java.lang.Object with Y with X = $anon$1@188c838
scala> yx.a
X
Y
res1: Int = 1
में प्रोग्रामिंग स्काला लेखकों सार कक्षाएं बनाने कि एक शास्त्रीय वस्तु उन्मुख "है-एक" रिश्ते जबकि लक्षण रचना की एक स्केला तरह से कर रहे हैं का कहना है।
एब्सट्रैक्ट क्लासेस में व्यवहार हो सकता है - वे कंस्ट्रक्टर आर्ग (जो लक्षण नहीं कर सकते हैं) के साथ मानकीकृत हो सकते हैं और एक कार्यशील इकाई का प्रतिनिधित्व कर सकते हैं। इसके बजाय लक्षण केवल एक विशेषता, एक कार्यक्षमता का एक इंटरफ़ेस का प्रतिनिधित्व करते हैं।
trait Enumerable
बहुत सारे सहायक कार्यों के साथ परिभाषित करते हैं, तो मैं उन्हें व्यवहार नहीं कहूंगा, लेकिन केवल एक सुविधा के साथ जुड़ा कार्यक्षमता।