为什么我不能访问受保护的java方法,即使我已经扩展了类?

Mat*_*att 8 java inheritance protected

这是受保护方法的文档:

/** Converts jmusic score data into a MIDI Sequence */
protected  javax.sound.midi.Sequence scoreToSeq(Score score)
Run Code Online (Sandbox Code Playgroud)

我创建了这个小类来扩展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;

    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 17

(编辑:theycallmemorty的答案.给人以避免在您的情况下,这个问题的实际建议这个答案给出了为什么你必须听从这一建议,即为什么语言已经这样设计的原因.)

您只能访问与访问代码(或子类)类型相同的另一个对象的受保护成员 - 即使该成员是以超类型声明的.

Java语言规范,第6.6.2节:

设C是声明受保护成员m的类.仅允许在C的子类S的主体内进行访问.此外,如果Id表示实例字段或实例方法,则:

  • 如果访问是通过限定名称Q.Id,其中Q是ExpressionName,则当且仅当表达式Q的类型是S或S的子类时才允许访问.
  • 如果接入是由现场访问表达式E.Id,其中E是一个主要表达式,或通过一个方法调用表达式(.)E.Id,其中E是一个主要表达式,则接入是允许的,当且仅如果E的类型是S或S的子类.

这是为了允许类型访问与其自己的继承树相关的成员,而不会破坏其他类的封装.例如,假设我们有:

     A
    / \
   B   Other
  /
 C
Run Code Online (Sandbox Code Playgroud)

和A宣布受保护的成员x.如果没有规则按照它的方式工作,你可以通过将一个成员放入Other:

public int getX(A a)
{
    return a.x;
}
Run Code Online (Sandbox Code Playgroud)

并且只是调用传递一个B或的实例C- 该成员将有效地公开,因为你总是可以通过引入另一个类来解决它...不是一个好主意.根据当前规则,您必须创建子类BC- 您可能无法首先使用它.


the*_*rty 12

通过做这个:

MidiSynth synth = new MidiSynth();
sequence = synth.scoreToSeq(score); 
Run Code Online (Sandbox Code Playgroud)

你实际上没有利用你扩展MidiSynth类的事实.

如果你要尝试

this.scoreToSec(score);
Run Code Online (Sandbox Code Playgroud)

然后你会发现你有权访问受保护的功能.

  • 或者通过创建一个新的MidiSequence而不是MidiSynth(并改变合成变量的类型). (4认同)