2009-10-25 13 views
7

यहाँ संरक्षित विधि के लिए दस्तावेज़ है:मैं सुरक्षित जावा विधि तक क्यों नहीं पहुंच सकता हूं, मैंने सोचा कि मैंने कक्षा को बढ़ाया है?

/** Converts jmusic score data into a MIDI Sequence */ 
protected javax.sound.midi.Sequence scoreToSeq(Score score) 

और मैं वर्ग scoreToSeq विधि आता है कि से विस्तार करने के लिए इस छोटे से वर्ग बनाया:

public class MidiSequence extends MidiSynth{ 

    public Sequence getSequence(Score score){ 
     MidiSynth synth = new MidiSynth(); 
     Sequence sequence = null; 
     try 
     { 
        // Here I get the error saying that the method has 
        // protected access in MidiSynth 
      sequence = synth.scoreToSeq(score); 

     } 
     catch (InvalidMidiDataException e) 
     { 
      /* 
      * In case of an exception, we dump the exception 
      * including the stack trace to the console. 
      * Then, we exit the program. 
      */ 
      e.printStackTrace(); 
      System.exit(1); 
     } 

     return sequence; 

    } 
} 
+0

नजीब तोउन्सी (टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं): हालांकि, 'synth.scoreToSeq (स्कोर); 'कानूनी होना चाहिए। –

उत्तर

16

(संपादित करें: theycallmemorty's answer से बचने के लिए व्यावहारिक सलाह देता है यह समस्या आपके मामले में है। यह उत्तर आपको सलाह देता है कि आपको उस सलाह का पालन क्यों करना है, यानी भाषा को इस तरह से डिजाइन क्यों किया गया है।)

आप केवल प्रोटी तक पहुंच सकते हैं किसी अन्य ऑब्जेक्ट का cted सदस्य जो एक्सेस कोड (या उप-वर्ग) के समान प्रकार का होता है - भले ही सदस्य को सुपरटेप में घोषित किया गया हो।

Java Language Specification, section 6.6.2 से:

Let सी क्लास जिसमें एक संरक्षित सदस्य मीटर घोषित किया जाता है हो सकता है। प्रवेश , केवल सी के एक उपवर्ग एस इसके अलावा के शरीर के भीतर की अनुमति दी है, तो ईद एक दृष्टांत फ़ील्ड या उदाहरण विधि, तो अर्थ है है:

  • पहुँच एक योग्य नाम से है Q.Id , जहां क्यू एक ExpressionName है, तो पहुंच की अनुमति दी है, तो और ही अगर अभिव्यक्ति क्यू के प्रकार एस या एस
  • का एक उपवर्ग है पहुँच एक क्षेत्र का उपयोग अभिव्यक्ति द्वारा है E.Id, जहां ई प्राथमिक अभिव्यक्ति है, या एक विधि आमंत्रण अभिव्यक्ति ई.आईडी (...।), डब्ल्यू यहाँ ई एक प्राथमिक अभिव्यक्ति है, तो पहुँच की अनुमति दी है यदि और केवल यदि ई के प्रकार एस या एस
  • का एक उपवर्ग

यह एक प्रकार के लिए प्रासंगिक के सदस्यों का उपयोग करने की अनुमति देने के लिए है अन्य वर्गों के encapsulation को हराने के बिना, अपने विरासत पेड़। उदाहरण के लिए, मान लीजिए हमने:

 A 
    /\ 
    B Other 
/
C 

और एक एक संरक्षित सदस्य x घोषित कर दिया। जिस तरह से यह करता है काम कर शासन के बिना, आप Other में एक सदस्य डालकर दौर कैप्सूलीकरण मिल सकता है:

public int getX(A a) 
{ 
    return a.x; 
} 

और बस बुला कि B या C का एक उदाहरण में गुजर - सदस्य को प्रभावी ढंग से सार्वजनिक, बन जाएगा क्योंकि आप एक और वर्ग शुरू करके हमेशा इसके आसपास काम कर सकता है ... अच्छा विचार नहीं। वर्तमान नियम के साथ, आपको B या C उपclass करना होगा - जो आप पहले स्थान पर नहीं हो पाएंगे।

+1

मुझे लगता है कि मैं (ज्यादातर) जेएलएस अंश को समझता हूं :-), लेकिन काउंटररेक्स नमूना प्रतीत नहीं होता है। संरक्षित फ़ील्ड x ए या बी पर नहीं है, इसलिए इसे देखना अन्य के लिए ठीक होना चाहिए। यह बी या सी से अन्य फ़ील्ड का पर्दाफाश नहीं करता है बेशक यह ज्यादातर हैयरस्प्टिंग है क्योंकि उत्तर "spec कहता है" और यह हमारे लिए spec बदलने के लिए असंभव है :-) –

+0

@ जोन क्या करते हैं आपका मतलब है "क्योंकि आप अपनी दूसरी आखिरी पंक्ति में" एक और कक्षा शुरू करके हमेशा इसके आसपास काम कर सकते हैं "? – Geek

+1

@ गीक: कोई भी एक और वर्ग बना सकता है जो 'ए' बढ़ाता है और * ए 'के किसी अन्य * सबक्लास के उदाहरण के लिए पहुंच प्रदान करता है। –

12

ऐसा करने से:

MidiSynth synth = new MidiSynth(); 
sequence = synth.scoreToSeq(score); 

आप वास्तव में तथ्य यह है कि आप MidiSynth वर्ग का विस्तार किया है का लाभ ले रहे हैं।

आप

this.scoreToSec(score); 

कोशिश करना हो तो फिर आप आप की रक्षा समारोह के लिए उपयोग किया मिलेगा।

+4

या मिडीसिंथ की बजाय एक नई मिडीसिवेंस बनाकर (और synth चर के प्रकार को भी बदलना)। –

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