2016-10-20 15 views
6

private[this] टाइप करके स्कैला में हम एक निजी सदस्य क्लास के उस विशेष ऑब्जेक्ट द्वारा केवल पहुंच योग्य बना सकते हैं, और उसी वर्ग का कोई अन्य ऑब्जेक्ट तक नहीं पहुंच सकता है। यदि संभव हो, तो हम इसे अन्य भाषाओं में कैसे पूरा कर सकते हैं ... विशेष रूप से एफ #, एरलांग, और क्लोजर?मैं एक निजी सदस्य ऑब्जेक्ट-एन्सेप्लेटेड कैसे बना सकता हूं?

+1

यह एफ # में निश्चित रूप से संभव है और मैं भी ऐसा कैसे अन्य लोगों में इतना ग्रहण करेंगे –

+0

? क्या आप एक उदाहरण प्रदान कर सकते हैं? मैं – codingXeno

+2

खोज से कुछ भी https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/members/methods –

उत्तर

6

आपके बारे में क्या कह रहे हैं मूल रूप से बीच का अंतर है वस्तु उन्मुख डेटा एब्सट्रैक्शन और डेटा एब्सट्रैक्शन साथ सार डेटा प्रकार (एडीटी रों, भ्रमित नहीं होना चाहिए बीजगणित डेटा प्रकार के साथ, जिसे अक्सर "एडीटी" के रूप में भी संक्षिप्त किया जाता है)। (On Understanding Data Abstraction, RevisitedWilliam R. Cook द्वारा अपने Proposal for Simplified, Modern Definitions of "Object" and "Object Oriented", और Object-Oriented Programming Versus Abstract Data Types देखें।)

दो का एक ही सार डेटा प्रकार अलग-अलग विविधताएं एक-दूसरे के प्रतिनिधित्व (लेकिन अन्य सार डेटा प्रकार के उदाहरण का प्रतिनिधित्व) का निरीक्षण कर सकते हैं, जबकि एक ऑब्जेक्ट कभी किसी ऑब्जेक्ट के प्रतिनिधित्व का निरीक्षण नहीं कर सकता है, भले ही ऑब्जेक्ट समान प्रकार का उदाहरण हो। कुक इस संपत्ति को ऑब्जेक्ट-ओरिएंटेड डेटा एब्स्ट्रक्शन (और वास्तव में ऑब्जेक्ट-ओरिएंटेशन में सामान्य रूप से) की मौलिक और परिभाषित विशेषता के रूप में पहचानता है, और इसे ऑटोगोनोसिस (स्व-ज्ञान) कहते हैं। मैं Xenoagnosis (विदेशी-ज्ञान-ज्ञान) शब्द पसंद करता हूं, जिसे ग्लेन वेंडरबर्ग, रिक डी नटाले या देर से जिम वीरच, आईआईआरसी द्वारा लागू किया गया था, क्योंकि यह दोनों दृष्टिकोणों के बीच अंतर पर जोर देता है, अर्थात् वस्तुओं को नहीं पता अन्य वस्तुओं के बारे में।

स्कैला में, जैसा कि आपने देखा, ऑब्जेक्ट ओरिएंटेड डेटा एब्स्ट्रक्शन private[this] एक्सेस संशोधक के माध्यम से हासिल किया जा सकता है।

class TestPrivate { 
    private  val notReallyPrivate = 42 
    private[this] val privateIMeanIt = 23 

    def blowUp(other: TestPrivate) = { 
    other.notReallyPrivate 
    other.privateIMeanIt 
    } 
} 
// error: value privateIMeanIt is not a member of TestPrivate 

Erlang में, एक वस्तु के बराबर एक प्रक्रिया है, और प्रक्रियाओं को पूरी तरह से भाषा अर्थ विज्ञान से समाहित हैं (वे भी अपने स्वयं के कचरा-एकत्र स्मृति है)। वे एक अलग महाद्वीप पर एक अलग मशीन पर भी रह सकते हैं, आखिरकार, प्रस्तुति का खुलासा करना अव्यवहारिक है। आप एक प्रक्रिया को एक संदेश भेजते हैं, और प्रक्रिया अपने निर्णय में पूरी तरह से स्वायत्त है कि संदेश के साथ क्या करना है और इसका जवाब कैसे देना है। सब कुछ मूल रूप से private[this] है।

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

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

interface ITestPrivate { 
    default int thisIsPublic() { return 0; } 

    default void blowUp1(ITestPrivate other) { 
    other.thisIsPublic(); 
    other.privateIMeanIt(); 
    } 
} 

class TestPrivate implements ITestPrivate { 
    private int privateIMeanIt() { return 23; } 

    void blowUp2(TestPrivate other1, ITestPrivate other2) { 
    other1.notReallyPrivate(); // works 
    other2.notReallyPrivate(); // doesn't 
    } 
} 

ऐसा भी F♯ में संभव हो जाना चाहिए, F♯ supports interfaces as well के बाद से।

+0

बीटीडब्ल्यू: यदि कोई व्यक्ति जो एर्लांग, क्लोजर, एफए, या जावा से अधिक परिचित है, उदाहरणों की आपूर्ति/सुधार करना चाहता है, आगे बढ़ें! –

+0

एक टिप्पणी मैं इस उत्कृष्ट उत्तर में और @ सैमस्टेप की इस प्रश्न पर टिप्पणी जोड़ूंगा: अक्सर जब कोई ऑब्जेक्ट या बंद करने के अंदर किसी "सदस्य" चर तक पहुंच प्रतिबंधित करना चाहता है, तो उद्देश्य मूल्य बदलने की क्षमता को प्रतिबंधित करना है परिवर्तनीय के। चूंकि क्लोजर को कार्यात्मक प्रोग्रामिंग के लिए डिज़ाइन किया गया है, एक सामान्य नियम के रूप में एक चर के मूल्य * को कभी भी बदला नहीं जा सकता * एक बार परिभाषित किया गया। इससे एक चर के उपयोग को छिपाने के लिए प्रेरणा कम हो जाती है। (एक चर को एक विशेष मान देना संभव है, उदाहरण के लिए 'परमाणु' का उपयोग करना, जो परोक्ष रूप से बदलते मूल्यों की अनुमति देता है, लेकिन इसके लिए अतिरिक्त चरणों की आवश्यकता होती है।) – Mars

2

कृपया @ जॉनपाल्मर की टिप्पणी और Access Control देखें। जिसे आसानी से Google के साथ पाया जा सकता है।

type TestPrivate(x) = 
    let y = x - 10 
    member private __.X() = 10 
    member __.Z() = x + 10 
    member __.Y = __.X() 

let test = TestPrivate(5) 
test.Z() //val it : int = 15 
test.Y //val it : int = 10 
test.X() 

त्रुटि FS0491: किसी सदस्य या वस्तु निर्माता 'एक्स' सुलभ नहीं है। निजी सदस्यों को केवल घोषणा प्रकार से बुद्धिमानी से पहुंचा जा सकता है। संरक्षित सदस्यों को केवल विस्तारित प्रकार से एक्सेस किया जा सकता है और को आंतरिक लैम्ब्डा एक्सप्रेस आयनों से एक्सेस नहीं किया जा सकता है।

संपादित

type TestPrivate(x:string) = 
    let totallyPrivate = x 
    member private __.PrivateX = x 
    member __.FromOther(other:TestPrivate) = 
     __.PrivateX + "-" + other.Y + "-" + other.PrivateX + "-" + totallyPrivate 
    member __.Y = __.PrivateX 

let thisTest = TestPrivate("this") 
let otherTest = TestPrivate("other") 

thisTest.FromOther(otherTest) //val it : string = "this-other-other-this" 
otherTest.FromOther(thisTest) //val it : string = "other-this-this-other" 
thisTest.FromOther(thisTest) //val it : string = "this-this-this-this" 
otherTest.FromOther(otherTest) //val it : string = "other-other-other-other" 

तो this उदाहरण पाठ्यक्रम पहुँच totallyPrivate की, लेकिन न तो this या other उपयोग कर सकते हैं कर सकते हैं के अन्य बाध्यकारी करते हैं, हालांकि वे दूसरे की निजी संपत्ति पर प्राप्त कर सकते हैं।

+2

में उपलब्ध नहीं है के लिए पूछता है यह वही है ओ पी * करने के लिए उदाहरण के लिए, का उपयोग प्रतिबंध पूछता नहीं है * (प्रकार नहीं) .NET – CaringDev

+2

बीटीडब्लू में उपलब्ध नहीं हैं: Google के लिए आपका स्नॉटी लिंक उचित नहीं है, क्योंकि प्रश्न पढ़ने से यह पता चला होगा: * ... और उसी वर्ग की दूसरी वस्तु इसे एक्सेस नहीं कर सकती है ... * – CaringDev

+1

@ करिंगडेव - यह सच है; हालांकि, 'लेट' बाध्यकारी वास्तव में दर्शाता है कि ओपी क्या पूछता है: कोई अन्य उदाहरण उस मूल्य तक पहुंचने के लिए बाध्य नाम का उपयोग नहीं कर सकता है। – kvb

3

एफ # public, internal और privateaccess control specifiers है। Scalas अधिक प्रतिबंधात्मक private[this] जो करने के लिए एक प्रकार का एक उदाहरण पहुँच सीमित करता है और न ही प्रकार एक विनिर्देशक के रूप में उपलब्ध नहीं है, तो भी private (सबसे एफ # में प्रतिबंधात्मक) एक other उदाहरण के सदस्यों पहुँचा जा सकता है। class let bindings उदाहरण-निजी हैं, हालांकि:

type Foo(x) = 
    let totallyPrivate = x 
    member private(*[this]*) __.Bar = x 
    member this.Baz (other : Foo) = 
     // other.Bar not accessible in Scala 
     this.Bar + other.Bar + totallyPrivate 
     // the field, constructor or member 'totallyPrivate' is not defined 
     // other.totallyPrivate 
+0

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

+2

आप कक्षा में 'चलो' बाध्यकारी का उपयोग कर सकते हैं, जो ओपी की इच्छाओं को ठीक से प्राप्त करता है (और बाइंडिंग का रूप यह इंगित करता है, क्योंकि यह प्रकार के सदस्य के रूप में बाध्य नहीं है)। – kvb

+0

@kvb यह इंगित करने के लिए धन्यवाद। मैंने तदनुसार अपना जवाब अपडेट किया। – CaringDev

1

जैसा कि @ जोर्गममिताग के उत्तर पर मेरी टिप्पणी द्वारा सुझाया गया है, मैं @ सैमस्टेप की टिप्पणी से सहमत हूं कि आप क्या करना चाहते हैं, कोडिंगएक्सो, क्लोजर में शायद ही कभी समझ में आएगा। हालांकि, यह एक अच्छा अभ्यास है, हालांकि, आम लिस्प या योजना में, और क्लोजर में केवल थोड़ा कठिन है। यहाँ आप क्या अनुरोध किया की तरह कुछ का एक बहुत ही सरल उदाहरण है:

(def getit-and-setit (let [x (atom 42)] 
         [(fn [] @x), (fn [new-x] (reset! x new-x))])) 

यहाँ हम एक स्थानीय चर x जिसका मूल्य एक "परमाणु", यानी कुछ है कि एक मूल्य है कि एक नए मूल्य के साथ प्रतिस्थापित किया जा सकता का आयोजन करेगा है परिभाषित किया। (@ या deref का उपयोग करके परमाणु की सामग्री निकाली जा सकती है। इसे reset! या कुछ अन्य उपयोगी ऑपरेटरों का उपयोग करके प्रतिस्थापित किया जा सकता है।) फिर हम एक दो-तत्व वेक्टर लौटते हैं। प्रत्येक तत्व एक समारोह है। (अल्पविराम आमतौर पर प्रयोग किया जाता है नहीं है, लेकिन यह अनुमति दी है और इस कोड साफ कर दिया है।)

(def get-it (first getit-and-setit)) 
(def set-it! (second getit-and-setit)) 

यहाँ पहले समारोह निकाला जाता है और एक नया वेरिएबल get-it परिभाषित अपने मूल्य के रूप में कार्य करने के लिए। और हमने अन्य कार्य को इसके मूल्य के रूप में रखने के लिए set-it! परिभाषित किया।

get-it रिटर्न परमाणु x का मूल्य है कि की सामग्री:

(set-it! 5) 
(get-it) ;==> 5 

वहाँ x तक पहुँचने के लिए कोई तरीके हैं:

(get-it) ;==> 42 

set-it! एक नया मान के साथ परमाणु की सामग्री को बदल get-it और set-it! के अलावा। x "निजी" है।

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

दूसरी ओर, यदि आप एक Clojure defrecord संरचना के घटकों के लिए उपयोग को प्रतिबंधित करना चाहता था, मुझे नहीं लगता कि आप ऐसा कर सकते, ऊपर दिए गए एक तरह एक विधि का उपयोग कर को छोड़कर है। आप इसे संबंधित deftype डेटा संरचना के साथ कर सकते हैं, लेकिन इसका आमतौर पर जावा इंटरऑप के लिए उपयोग किया जाता है।

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