Domanda

Ecco la documentazione per il metodo protetto:

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

E ho creato questa piccola classe per estendere la classe da cui proviene il metodo 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;

    }
}
È stato utile?

Soluzione

(EDIT: risposta di theycallmemorty fornisce consigli pratici per evitare questo problema nel tuo caso. Questa risposta fornisce i motivi per cui devi seguire quel consiglio, ovvero perché la lingua è stata progettata in questo modo.)

Puoi accedere solo a un membro protetto di un altro oggetto dello stesso tipo del codice di accesso (o di una sottoclasse), anche se il membro è dichiarato in un supertipo.

Dalla Specifica della lingua Java, sezione 6.6.2 :

  

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

     
      
  • Se l'accesso avviene con 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 avviene tramite un'espressione di accesso al campo E.Id, dove E è un primario   espressione o mediante una chiamata al metodo   espressione E.Id (...), dove E è a   Espressione primaria, quindi l'accesso è   consentito se e solo se il tipo di E   è S o una sottoclasse di S.
  •   

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

     A
    / \
   B   Other
  /
 C

e A hanno dichiarato un membro protetto x . Senza che la regola funzioni nel modo in cui funziona, potresti ottenere l'incapsulamento circolare inserendo un membro in Altro :

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

e chiamandolo semplicemente passando in un'istanza di B o C - il membro diventerebbe effettivamente pubblico, perché potresti sempre aggirare il problema introducendo un'altra classe .. . non è una buona idea. Con la regola attuale, dovresti sottoclassare B o C - cosa che potresti non essere in grado di fare in primo luogo.

Altri suggerimenti

In questo modo:

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

In realtà non stai sfruttando il fatto che hai esteso la classe MidiSynth.

Se dovessi provare

this.scoreToSec(score);

Quindi scoprirai di avere accesso alla funzione protetta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top