2011-01-13 14 views
21

ठीक है, मैं समझाऊंगा कि मैं इस सवाल से क्यों पूछता हूं। मैं इन दिनों लिफ्ट 2.2 स्रोत कोड पढ़ना शुरू करता हूं। यदि आप पहले लिफ्ट स्रोत कोड पढ़ना चाहते हैं तो यह अच्छा है।क्यों लोग स्केल में किसी अन्य वस्तु के अंदर वर्ग, विशेषता, वस्तु को परिभाषित करते हैं?

लिफ्ट में, मैंने पाया कि, आंतरिक वर्ग और आंतरिक विशेषता को परिभाषित करने के लिए बहुत अधिक उपयोग किया जाता है।

ऑब्जेक्ट Menu में 2 आंतरिक लक्षण और 4 आंतरिक कक्षाएं हैं। ऑब्जेक्ट Loc में 18 आंतरिक कक्षाएं, 5 आंतरिक लक्षण, 7 आंतरिक वस्तुएं हैं।

इस तरह के कई कोड लिखते हैं। मैं जानना चाहता हूं कि लेखक इस तरह क्यों लिखते हैं।

  • यह है क्योंकि यह लेखक का व्यक्तिगत स्वाद या भाषा सुविधा का एक शक्तिशाली फायदा नहीं है?
  • क्या इस तरह के उपयोग के लिए कोई व्यापार-बंद है?

उत्तर

18

2.8 से पहले, आपको पैकेज और ऑब्जेक्ट्स के बीच चयन करना पड़ा। संकुल के साथ समस्या यह है कि उनमें स्वयं के तरीके या vals शामिल नहीं हो सकते हैं। तो आपको उन सभी को किसी अन्य वस्तु के अंदर रखना होगा, जो अजीब हो सकता है। का निरीक्षण करें:

object Encrypt { 
    private val magicConstant = 0x12345678 
    def encryptInt(i: Int) = i^magicConstant 
    class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] { 
    def hasNext = ii.hasNext 
    def next = encryptInt(ii.next) 
    } 
} 

अब आप कर सकते हैं import Encrypt._ और वर्ग EncryptIterator के रूप में विधि encryptInt तक पहुँचने में रूप में अच्छी तरह। हैंडी!

इसके विपरीत,

package encrypt { 
    object Encrypt { 
    private[encrypt] val magicConstant = 0x12345678 
    def encryptInt(i: Int) = i^magicConstant 
    } 
    class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] { 
    def hasNext = ii.hasNext 
    def next = Encrypt.encryptInt(ii.next) 
    } 
} 

यह एक विशाल अंतर नहीं है, लेकिन यह उपयोगकर्ता आयात encrypt._ और encrypt.Encrypt._ या अधिक से अधिक Encrypt.encryptInt लेखन रखने के लिए दोनों बनाता है। क्यों न केवल किसी ऑब्जेक्ट का उपयोग करें, जैसा कि पहले पैटर्न में है? (वास्तव में कोई प्रदर्शन जुर्माना नहीं है, क्योंकि नेस्टेड कक्षाएं वास्तव में हुड के नीचे जावा आंतरिक कक्षाएं नहीं हैं; वे केवल नियमित कक्षाएं हैं जहां तक ​​JVM जानता है, लेकिन फैंसी नामों के साथ जो आपको बताते हैं कि वे घोंसले हैं।)

2 में।8, आप अपना केक ले सकते हैं और इसे भी खा सकते हैं: चीज़ को पैकेज ऑब्जेक्ट पर कॉल करें, और कंपाइलर आपके लिए कोड फिर से लिख देगा, इसलिए यह वास्तव में हुड के नीचे दूसरा उदाहरण जैसा दिखता है (ऑब्जेक्ट Encrypt को छोड़कर वास्तव में package आंतरिक रूप से कहा जाता है) , लेकिन नेमस्पेस के मामले में पहले उदाहरण की तरह व्यवहार करता है - एक अतिरिक्त आयात की आवश्यकता के बिना vals और defs सही हैं।

इस प्रकार, प्रोजेक्ट जो प्री-2.8 शुरू किए गए थे, अक्सर सामानों का उपयोग करने के लिए सामानों का उपयोग करते थे जैसे कि वे एक पैकेज थे। पोस्ट -88, मुख्य प्रेरणाओं में से एक को हटा दिया गया है। (लेकिन स्पष्ट होने के लिए, किसी ऑब्जेक्ट का उपयोग करके अभी भी चोट नहीं पहुंची है; यह और अधिक है कि यह अवधारणात्मक रूप से भ्रामक है कि इसका प्रदर्शन या नॉटन पर नकारात्मक प्रभाव पड़ता है।)

(पीएस कृपया, कृपया वास्तव में प्रयास करने की कोशिश न करें उदाहरण या मजाक के अलावा किसी भी तरह से एन्क्रिप्ट करें!)

+0

क्या किसी ऑब्जेक्ट में नेस्टेड क्लास जावा की स्थिर आंतरिक कक्षा के समान है? अगर मैं एक साथी वस्तु में 100 आंतरिक वर्ग, या 100 आंतरिक वस्तु डालता हूं, तो संकलक उनका इलाज कैसे करेगा? बिल्कुल कोई प्रदर्शन जुर्माना नहीं? – Sawyer

+1

कक्षा या ऑब्जेक्ट 'फू' के अंदर एक नेस्टेड क्लास 'बार' को एक आंतरिक वर्ग के रूप में लागू नहीं किया गया है, लेकिन 'फू $ बार' नाम वाला _outer_ क्लास है, और केवल तभी इसे अपने मूल वर्ग का उपयोग करने की आवश्यकता है, (छिपी हुई छिपी हुई) फ़ील्ड जो माता-पिता को इंगित करती है। JVM की बजाय संकलक यह लागू करता है कि आप इसे सही तरीके से उपयोग करते हैं, और किसी ऑब्जेक्ट के मामले में, यह जानता है कि केवल एक ही है इसलिए उसे उस फ़ील्ड को संग्रहीत करने की आवश्यकता नहीं है। –

3

यह दोनों हो सकता है। अन्य चीजों के अलावा, एक आंतरिक वर्ग/विशेषता के उदाहरण के माता-पिता के चर के लिए उपयोग होता है। आंतरिक वर्गों को मूल उदाहरण के साथ बनाया जाना चाहिए, जो बाहरी प्रकार का एक उदाहरण है।

अन्य मामलों में, यह शायद आपके object उदाहरण में, निकट से संबंधित चीजों को समूहीकृत करने का एक तरीका है। ध्यान दें कि विशेषता LocParam सील कर दी गई है, जिसका अर्थ है कि सभी उप-वर्गों को एक ही संकलन इकाई/फ़ाइल में होना चाहिए।

+0

समूह से संबंधित चीजों के लिए ऑब्जेक्ट का उपयोग करें मुझे अच्छा नहीं लगता है, मुझे लगता है कि यह पैकेज का उपयोग है। – Sawyer

+0

@Zwcat: आप जो कहते हैं उसके लिए बहुत सच्चाई है। सुविधा के मामले में, हालांकि, इन सभी छोटी चीजों को एक ही निर्देशिका में इतनी सारी फाइलों की बजाय एक फ़ाइल में कम परेशानी हो सकती है। मुहरबंद कीवर्ड का उपयोग करके उन्हें एक ही फाइल में रखना और उन्हें किसी ऑब्जेक्ट में लपेटना आवश्यक होता है, जो कम गन्दा लगते हैं। – sblundy

2

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

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