2012-10-09 4 views
17

आकर्षक शीर्षक के लिए खेद है। ;-)क्या मैं स्कैला में कोई पैकेज-प्राइवेट क्लास नहीं रख सकता हूं?

मैं स्काला में एक पैकेज-निजी विधि के साथ एक पैकेज-निजी वर्ग बनाना चाहते हैं, तो मेरी कक्षा इस तरह कुछ हद तक दिखता है:

package net.java.truevfs.ext.pace 

import ... 

private[pace] abstract class AspectController(controller: FsController) 
extends FsDecoratingController(controller) { 

    private[pace] def apply[V](operation: => V): V 

    ... // lots of other stuff 
} 

हालांकि, अगर मैं javap का उपयोग क्या जांच करने के लिए स्काला संकलक प्रभावी रूप से बनाता है, मैं कुछ इस तरह मिलती है:

$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController 
Compiled from "AspectController.scala" 
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{ 
    public abstract java.lang.Object apply(scala.Function0); 
    ... 
} 

इसका मतलब यह है कि हालांकि स्काला संकलक का उपयोग प्रतिबंधों का सम्मान हो सकता है, मैं अभी भी इस वर्ग के किसी भी जावा कोड है, जो एक स्पष्ट कैप्सूलीकरण उल्लघंन होने पर कह सकते हैं।

क्या मुझे कुछ याद आ रही है? क्या इस काम को इरादे से बनाने का कोई तरीका है?

+2

+1 अजीब शीर्षक –

उत्तर

15

@ रेगिस 'जवाब के अलावा, कारण स्काला संकलक वर्ग पैकेज-निजी है, क्योंकि स्काला यह नियम द्वारा अन्य पैकेजों से पहुँचा जा सकता नहीं है। जैसे

package net.java.truevfs.ext.pace.subpackage 
import net.java.truevfs.ext.pace.AspectController 

class Subclass extends AspectController { ... } 

स्काला में कानूनी है, लेकिन जावा में net.java.truevfs.ext.pace.subpackage से कक्षाएं net.java.truevfs.ext.pace से पैकेज-निजी कक्षाएं उपयोग नहीं कर सकते।

+0

+1। मैं वास्तव में इसे इंगित करने जा रहा था। –

+0

अच्छा बिंदु - मुझे यह नहीं पता था। –

+0

खैर, इसका वास्तव में मतलब है कि पैकेज-निजी वर्ग की अवधारणा स्कैला में मौजूद नहीं है। बहुत बुरा, क्योंकि मेरे लिए यह मेरे जावा टूल का प्राथमिक तत्व रहा है जो फोस्टर एनकैप्यूलेशन के लिए सेट है (मैं समझता हूं कि यह सुरक्षा केवल भाषा स्तर पर ही काम करती है)। –

9

आप कुछ भी याद नहीं कर रहे हैं। स्कैला में कई एक्सेस रेस्ट्रिकिटन जावा में और जेवीएम स्तर पर बराबर नहीं हैं। अतिरिक्त जानकारी स्पष्ट रूप से .class फ़ाइल में ठीक है, लेकिन कस्टम एनोटेशन के रूप में है कि केवल स्कैला संकलक ही व्याख्या करेगा। स्कैला ऑब्जेक्ट मॉडल केवल आंशिक रूप से जेवीएम ऑब्जेक्ट मॉडल से मेल खा सकता है, और जावा कंपाइलर केवल इस आंशिक मॉडल को देखेगा। मैं कहूंगा कि यह मैच बहुत करीब है और स्कैला कंपाइलर जावा इंटरऑपरेबिलिटी पर बहुत अच्छा काम करता है, लेकिन नोटिंग का सही है। अर्थात्, net.java.truevfs.ext.pace की सबपैकेज:

+0

के लिए मुझे ऐसा लगा और वर्ग पर @ scala.reflect.ScalaSignature एनोटेशन को मान्यता दी। हालांकि मुझे चिंता है कि यह encapsulation का स्पष्ट उल्लंघन है और जब तक आप जावा कोड से कुछ भी कॉल कर सकते हैं तब तक एक्सेस संशोधक का उपयोग पूरी तरह से व्यर्थ हो जाता है। –

+3

वैसे, सामान्य रूप से संशोधक तक पहुंचने वाली एक ही डिग्री के लिए "व्यर्थ" व्यर्थ हैं, क्योंकि आप उन्हें प्रतिबिंब/पॉइंटर्स के माध्यम से हमेशा बाईपास कर सकते हैं। – themel

+0

मैं कहूंगा कि आप जावा से "कुछ भी" कह सकते हैं। यदि आप 'लागू 'सादा निजी बनाते हैं (जैसा कि' गति 'के लिए निजी है) तो आप देखेंगे कि विधि वास्तव में .class फ़ाइल में निजी रूप से चिह्नित है। ऐसा इसलिए है क्योंकि स्कैला और जावा में एक निजी विधि की अवधारणा सटीक रूप से वही है, इसलिए संकलक इसे निजी के रूप में चिह्नित कर सकता है। दूसरी तरफ, एक पैकेज के लिए निजी विधि की अवधारणा जावा/जेवीएम में मौजूद नहीं है। –

1

नहीं वास्तव में एक 100% सही जवाब ...

आप एक पैकेज वस्तु बना सकते हैं अगर मैं एक निजी वर्ग के साथ वहाँ में कुछ फैंसी सामान करना चाहते हैं। पैकेज ऑब्जेक्ट किसी अन्य पैकेज की तरह एक्सेस किया जाता है। कक्षा MyClass पैकेज पैकेज के लिए निजी पैकेज है। हालांकि यह निजी पैकेज नहीं है।

package object com.jasongoodwin.foo { 
    private class MyClass 

    class AnotherClass { 
    val myClass = new MyClass 
    } 
} 
संबंधित मुद्दे