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

时间:2009-10-25 21:54:51

标签: java inheritance protected

以下是受保护方法的文档:

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

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

    }
}

2 个答案:

答案 0 :(得分:17)

(编辑:theycallmemorty's answer给出了在你的案例中避免这个问题的实用建议。这个答案给出了为什么你必须遵循这个建议的原因,即为什么语言是这样设计的。)

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

来自Java Language Specification, section 6.6.2

  

让C成为a的类   保护成员m被声明。访问   只允许在一个体内   C的子类S.此外,如果Id   表示实例字段或实例   方法,然后:

     
      
  • 如果访问是通过限定名称Q.Id,其中Q是ExpressionName,   然后,如果和,则允许访问   只有表达式Q的类型   是S或S的子类。
  •   
  • 如果访问是通过字段访问表达式E.Id,其中E是主要   表达式,或通过方法调用   表达式E.Id(...),其中E是a   主要表达,然后访问是   当且仅当E的类型允许   是S或S的子类。
  •   

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

     A
    / \
   B   Other
  /
 C

和A声明受保护的成员x。如果没有规则按照它的方式工作,你可以通过在Other中添加一个成员来实现封装:

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

并且只是调用传递BC的实例 - 该成员将有效地公开,因为您可以通过引入另一个类来解决它...不是一个好主意。使用当前规则,您必须创建子类BC - 您可能无法将其置于最初。

答案 1 :(得分:12)

通过这样做:

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

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

如果你要尝试

this.scoreToSec(score);

然后你会发现你可以访问受保护的功能。