Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
679 views
in Technique[技术] by (71.8m points)

inheritance - Why can't I access protected java method even thought I've extended the class?

Here's the documentation for the protected method:

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

And I made this little class to extend the class that scoreToSeq method comes from:

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;

    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(EDIT: theycallmemorty's answer gives the practical advice to avoiding this problem in your case. This answer gives the reasons for why you have to follow that advice, i.e. why the language has been designed that way.)

You can only access a protected member of another object which is of the same type as the accessing code (or a subclass) - even though the member is declared in a supertype.

From the Java Language Specification, section 6.6.2:

Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:

  • If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
  • If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.

This is to allow a type to access members relevant to its own inheritance tree, without defeating encapsulation of other classes. For example, suppose we have:

     A
    / 
   B   Other
  /
 C

and A declared a protected member x. Without the rule working the way it does, you could get round encapsulation by putting a member in Other:

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

and just calling that passing in an instance of B or C - the member would effectively become public, because you could always work around it by introducing another class... not a good idea. With the current rule, you'd have to subclass B or C - which you may not be able to in the first place.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...