2009-10-25 14 views
7

Ecco la documentazione per il metodo protetto:perché non riesco ad accedere al metodo java protetto, anche se ho pensato di estendere la classe?

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

e ho fatto questa piccola classe per estendere la classe che il metodo scoreToSeq proviene da:

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

Da Najib Tounsi (non abbastanza rappresentante per commentare): Anche se 'synth.scoreToSeq (punteggio);' dovrebbe essere legale. –

risposta

16

(EDIT: theycallmemorty's answer dà i consigli pratici per evitare questo problema nel tuo caso Questa risposta spiega i motivi per cui devi seguire quel consiglio, cioè perché il linguaggio è stato progettato in questo modo.)

È possibile accedere solo a un prote membro cted di un altro oggetto che è dello stesso tipo del codice di accesso (o una sottoclasse) - anche se il membro è dichiarato in un supertipo.

Dal Java Language Specification, section 6.6.2:

sia C la classe in cui viene dichiarato un membro protetto m. Accesso è consentito solo all'interno del corpo di un sottoclasse S di C. Inoltre, se Id indica un campo di istanza o un metodo esempio , quindi:

  • Se l'accesso è da un nome qualificato Q.Id , dove Q è un ExpressionName, quindi l'accesso è consentito se e solo se il tipo dell'espressione Q è S o una sottoclasse di S.
  • Se l'accesso è da un'espressione accesso campo E.Id, dove E è un'espressione primaria oppure un'espressione di metodo espressione E.Id (...), W qui E è un espressione primaria, allora l'accesso è consentito se e solo se il tipo di E è S o una sottoclasse di S.

Questo per consentire un tipo di accedere ai membri rilevanti per il suo albero ereditario, senza sconfiggere l'incapsulamento di altre classi. Ad esempio, supponiamo di avere:

 A 
    /\ 
    B Other 
/
C 

e A dichiarata membro protetto x. Senza la regola di lavoro il modo in cui lo fa, si potrebbe ottenere l'incapsulamento rotonda mettendo un membro in Other:

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

e solo chiamando che passando un'istanza di B o C - il membro sarebbe effettivamente diventata pubblica, perché si potrebbe sempre aggirarlo introducendo un'altra classe ... non è una buona idea. Con la regola attuale, dovresti creare una sottoclasse di B o C, che potresti non essere in grado, in primo luogo.

+1

Penso di (per lo più) di capire l'estratto di JLS :-), ma il controesempio non sembra convincente. Il campo protetto x è su A non su B o C quindi dovrebbe essere ok per gli altri per vederlo. Non espone altri campi né da B né da C. Ovviamente si tratta principalmente di hairsplitting poiché la risposta è "le specifiche lo dicono" ed è piuttosto improbabile per noi modificare le specifiche :-) –

+0

@Jon Cosa fare intendi per "perché potresti sempre aggirarlo introducendo un'altra classe" nella tua penultima riga? – Geek

+1

@Geek: chiunque potrebbe semplicemente creare un'altra classe che estende 'A' e fornisce l'accesso per un'istanza di * qualsiasi altra * sottoclasse di' A'. –

12

In questo modo:

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

non sono in realtà approfittando del fatto che hai esteso la classe MidiSynth.

Se si dovesse provare

this.scoreToSec(score); 

allora troverete si ha accesso alla funzione protetta.

+4

O creando un nuovo MidiSequence invece di un MidiSynth (e cambiando anche il tipo della variabile synth). –

Problemi correlati