2011-12-31 12 views
5

मैं ऐसी परिस्थिति में हूं जहां मुझे किसी अन्य पैकेज में परिभाषित विशेषता में मिश्रण करने की आवश्यकता है। परीक्षण में सहायता के लिए, इस विशेषता में एक संरक्षित विधि पैकेज योग्य है।किसी पैकेज द्वारा एक पैकेज द्वारा संरक्षित विधि को एक अलग पैकेज में

package A { 
    trait X { 
    protected[A] def method(arg: Int) 
    } 
} 

package B { 
    class Y extends A.X { 
    protected[A] def method(arg: Int) { } 
    } 
} 

scalac के साथ इस संकलन 2.9.1 पैदावार:

test.scala:9: error: A is not an enclosing class 
    protected[A] def method(arg: Int) { } 

इस में किसी भी अन्य पहुँच संशोधक परिणाम के लिए "सुरक्षित [एक]" वर्ग में वाई बदलना:

यहाँ एक उदाहरण है
test.scala:9: error: overriding method method in trait X of type (arg: Int)Unit; 
method method has weaker access privileges; it should be at least protected[A] 
    override protected def method(arg: Int) { } 

मेरा प्रश्न यह है: विशेषता एक्स की परिभाषा मानना ​​नहीं बदल सकता है, क्या कक्षा वाई में कोई बदलाव है जो इसे एक्स एक्स का विस्तार करने की अनुमति देगा? ('संरक्षित' पहुंच के कुछ स्तर को बनाए रखते हुए)

यदि यह संभव नहीं है, तो क्या इसके आसपास काम करने के लिए कोई अन्य अनुशंसित डिजाइन रणनीतियां हैं? ('विधि' सार्वजनिक बनाने के अलावा)

+0

मुझे यह जोड़ना चाहिए कि मैं सरल सवाल का जवाब देने की कोशिश कर रहा हूं कि यह डिज़ाइन द्वारा असंभव है, जैसे कि "सुरक्षित [ए] 'को' सार्वजनिक 'में बदलने का एकमात्र (सरल) तरीका है। पैकेज की परवाह किए बिना यह एक उप-वर्ग की तरह लगता है? या नहीं? – nu11ptr

+0

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

उत्तर

2

मैंने इसे एडाप्टर के साथ हल करने का अंत किया। जबकि मैं मूल विशेषता को नहीं बदल सकता, मैं एक ही पैकेज में एक और जोड़ सकता हूं (लेकिन अन्य कारणों से क्लास को उस पैकेज में रखने का अर्थ नहीं होगा)। कक्षा वाई में 'adapterMethod' बी को प्रयोग के रूप में पैकेज करने के लिए योग्य है, लेकिन अधिकतर यह मेरे उपयोग के मामले के लिए अनावश्यक है। स्केला 2.9.1 में निम्नलिखित compiles:

package A { 
    trait X { 
    protected[A] def method(arg: Int) 
    } 

    trait PackageAdapter { 
    protected[A] def method(arg: Int) { adapterMethod(arg) } 

    protected def adapterMethod(arg: Int) 
    } 
} 

package B { 
    class Y extends A.X with A.PackageAdapter { 
    protected[B] def adapterMethod(arg: Int) { } 
    } 
} 

मैं इस समाधान के बारे में पागल नहीं हूँ, लेकिन यह इतना बुरा नहीं है। कक्षा वाई एक अपवाद मामला है क्योंकि विशेषता वर्ग का उपयोग करने वाले शेष वर्ग पैकेज ए में हैं (कक्षा वाई कई अन्य कारणों से पैकेज बी में होना चाहिए)। कोई बेहतर विचार?

+0

क्या आप ए से बी प्राप्त कर सकते हैं: "पैकेज एबी {कक्षा वाई ..."? – TechNeilogy

+0

तकनीकी रूप से, हां, लेकिन यह कई अन्य कारणों से मनमानी और 'गलत' होगा क्योंकि ए और बी के पास एक दूसरे के साथ कुछ लेना देना नहीं है और प्रत्येक में कई कक्षाएं हैं। फिर भी सुझाव के लिए धन्यवाद। – nu11ptr

+0

अद्यतन: यह पता चला है कि मैं दो pacakages के बीच वर्ग वाई विभाजित करके कुछ ऐसा ही करूँगा। – nu11ptr

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