pourquoi ne puis-je pas accéder à la méthode Java protégée même si j'ai étendu la classe?

StackOverflow https://stackoverflow.com/questions/1622219

  •  06-07-2019
  •  | 
  •  

Question

Voici la documentation de la méthode protégée:

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

Et j'ai créé cette petite classe pour étendre celle de la méthode 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;

    }
}
Était-ce utile?

La solution

(EDIT: Theycallmemorty answer vous donne des conseils pratiques pour éviter ce problème dans votre cas. Cette réponse explique les raisons pour lesquelles vous devez suivre ces conseils, c.-à-d. Pourquoi le langage a été conçu de cette manière.)

Vous pouvez uniquement accéder à un membre protégé d'un autre objet du même type que le code d'accès (ou une sous-classe), même si le membre est déclaré dans un supertype.

Extrait de la Spécification du langage Java, section 6.6.2 :

  

Soit C la classe dans laquelle a   membre protégé m est déclaré. Accès   est autorisé uniquement dans le corps d'un   sous-classe S de C. En outre, si Id   dénote un champ ou une instance   méthode, puis:

     
      
  • Si l'accès se fait par un nom qualifié Q.Id, où Q est un nom d'expression,   alors l'accès est autorisé si et   seulement si le type de l'expression Q   est S ou une sous-classe de S.
  •   
  • Si l'accès se fait par une expression d'accès au champ E.Id, où E est un primaire   expression, ou par une invocation de méthode   expression E.Id (...), où E est un   Expression primaire, alors l'accès est   permis si et seulement si le type de E   est S ou une sous-classe de S.
  •   

Ceci permet à un type d'accéder aux membres pertinents pour son propre arbre d'héritage, sans compromettre l'encapsulation d'autres classes. Par exemple, supposons que nous ayons:

     A
    / \
   B   Other
  /
 C

et A ont déclaré un membre protégé x . Si la règle ne fonctionne pas comme elle le fait, vous pouvez contourner l’encapsulation en plaçant un membre dans Autre :

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

et en appelant simplement cela en passant une instance de B ou C - le membre deviendrait effectivement public, car vous pourriez toujours le contourner en introduisant une autre classe. . pas une bonne idée. Avec la règle actuelle, vous devez sous-classer B ou C - ce que vous ne pourrez peut-être pas en premier lieu.

Autres conseils

En procédant ainsi:

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

Vous ne tirez pas parti du fait que vous avez étendu la classe MidiSynth.

Si vous deviez essayer

this.scoreToSec(score);

Vous constaterez alors que vous avez accès à la fonction protégée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top